Monday, 30 January 2017

Tips and Tricks on C Programming :

*
Function pointers. You can use a table of function pointers to implement, e.g., fast indirect-threaded code interpreters (FORTH) or byte-code dispatchers, or to simulate OO-like virtual methods.
Then there are hidden gems in the standard library, such as qsort(),bsearch(), strpbrk(), strcspn() [the latter two being useful for implementing a strtok() replacement].
A misfeature of C is that signed arithmetic overflow is undefined behavior (UB). So whenever you see an expression such as x+y, both being signed ints, it might potentially overflow and cause UB.


*
More of a trick of the GCC compiler, but you can give branch indication hints to the compiler (common in the Linux kernel)
#define likely(x)       __builtin_expect((x),1)
#define unlikely(x)     __builtin_expect((x),0)
see: http://kerneltrap.org/node/4705
What I like about this is that it also adds some expressiveness to some functions.
void foo(int arg)
{
     if (unlikely(arg == 0)) {
           do_this();
           return;
     }
     do_that();
     ...
}
 
 
 *

int8_t
int16_t
int32_t
uint8_t
uint16_t
uint32_t
These are an optional item in the standard, but it must be a hidden feature, because people are constantly redefining them. One code base I've worked on (and still do, for now) has multiple redefinitions, all with different identifiers. Most of the time it's with preprocessor macros:
#define INT16 short
#define INT32  long
And so on.
 
*
The comma operator isn't widely used. It can certainly be abused, but it can also be very useful. This use is the most common one:
for (int i=0; i<10; i++, doSomethingElse())
{
  /* whatever */
}
But you can use this operator anywhere. Observe:
int j = (printf("Assigning variable j\n"), getValueFromSomewhere());
Each statement is evaluated, but the value of the expression will be that of the last statement evaluated.

*


initializing structure to zero
struct mystruct a = {0};
this will zero all stucture elements.

*
Multi-character constants:
int x = 'ABCD';
This sets x to 0x41424344 (or 0x44434241, depending on architecture).
EDIT: This technique is not portable, especially if you serialize the int. However, it can be extremely useful to create self-documenting enums. e.g.
enum state {
    stopped = 'STOP',
    running = 'RUN!',
    waiting = 'WAIT',
};
This makes it much simpler if you're looking at a raw memory dump and need to determine the value of an enum without having to look it up.
 
 
*

I never used bit fields but they sound cool for ultra-low-level stuff.
struct cat {
    unsigned int legs:3;  // 3 bits for legs (0-4 fit in 3 bits)
    unsigned int lives:4; // 4 bits for lives (0-9 fit in 4 bits)
    // ...
};

cat make_cat()
{
    cat kitty;
    kitty.legs = 4;
    kitty.lives = 9;
    return kitty;
}
This means that sizeof(cat) can be as small as sizeof(char).
 
*

C has a standard but not all C compilers are fully compliant (I've not seen any fully compliant C99 compiler yet!).
That said, the tricks I prefer are those that are non-obvious and portable across platforms as they rely on the C semantic. They usually are about macros or bit arithmetic.
For example: swapping two unsigned integer without using a temporary variable:
...
a ^= b ; b ^= a; a ^=b;
...
or "extending C" to represent finite state machines like:
FSM {
  STATE(x) {
    ...
    NEXTSTATE(y);
  }

  STATE(y) {
    ...
    if (x == 0) 
      NEXTSTATE(y);
    else 
      NEXTSTATE(x);
  }
}
that can be achieved with the following macros:
#define FSM
#define STATE(x)      s_##x :
#define NEXTSTATE(x)  goto s_##x
In general, though, I don't like the tricks that are clever but make the code unnecessarily complicated to read (as the swap example) and I love the ones that make the code clearer and directly conveying the intention (like the FSM example).
 
 
*

Interlacing structures like Duff's Device:
strncpy(to, from, count)
char *to, *from;
int count;
{
    int n = (count + 7) / 8;
    switch (count % 8) {
    case 0: do { *to = *from++;
    case 7:      *to = *from++;
    case 6:      *to = *from++;
    case 5:      *to = *from++;
    case 4:      *to = *from++;
    case 3:      *to = *from++;
    case 2:      *to = *from++;
    case 1:      *to = *from++;
               } while (--n > 0);
    }
}
 
 
*
I'm very fond of designated initializers, added in C99 (and supported in gcc for a long time):
#define FOO 16
#define BAR 3

myStructType_t myStuff[] = {
    [FOO] = { foo1, foo2, foo3 },
    [BAR] = { bar1, bar2, bar3 },
    ...
The array initialization is no longer position dependent. If you change the values of FOO or BAR, the array initialization will automatically correspond to their new value.
 
 
*
C99 has some awesome any-order structure initialization.
struct foo{
  int x;
  int y;
  char* name;
};

void main(){
  struct foo f = { .y = 23, .name = "awesome", .x = -38 };
}
  
 
*

anonymous structures and arrays is my favourite one. (cf. http://www.run.montefiore.ulg.ac.be/~martin/resources/kung-f00.html)
setsockopt(yourSocket, SOL_SOCKET, SO_REUSEADDR, (int[]){1}, sizeof(int));
or
void myFunction(type* values) {
    while(*values) x=*values++;
}
myFunction((type[]){val1,val2,val3,val4,0});
it can even be used to instanciate linked lists...
 
*
gcc has a number of extensions to the C language that I enjoy, which can be found here. Some of my favorites are function attributes. One extremely useful example is the format attribute. This can be used if you define a custom function that takes a printf format string. If you enable this function attribute, gcc will do checks on your arguments to ensure that your format string and arguments match up and will generate warnings or errors as appropriate.
int my_printf (void *my_object, const char *my_format, ...)
            __attribute__ ((format (printf, 2, 3)));
 
 
*
the (hidden) feature that "shocked" me when I first saw is about printf. this feature allows you to use variables for formatting format specifiers themselves. look for the code, you will see better:
#include <stdio.h>

int main() {
    int a = 3;
    float b = 6.412355;
    printf("%.*f\n",a,b);
    return 0;
}
the * character achieves this effect.
 
 
*
Constant string concatenation
I was quite surprised not seeing it allready in the answers, as all compilers I know of support it, but many programmers seems to ignore it. Sometimes it's really handy and not only when writing macros.
Use case I have in my current code: I have a #define PATH "/some/path/" in a configuration file (really it is setted by the makefile). Now I want to build the full path including filenames to open ressources. It just goes to:
fd = open(PATH "/file", flags);
Instead of the horrible, but very common:
char buffer[256];
snprintf(buffer, 256, "%s/file", PATH);
fd = open(buffer, flags);
Notice that the common horrible solution is:
  • three times as long
  • much less easy to read
  • much slower
  • less powerfull at it set to an arbitrary buffer size limit (but you would have to use even longer code to avoid that without constant strings contatenation).
  • use more stack space
 
 
*
Struct assignment is cool. Many people don't seem to realize that structs are values too, and can be assigned around, there is no need to use memcpy(), when a simple assignment does the trick.
For example, consider some imaginary 2D graphics library, it might define a type to represent an (integer) screen coordinate:
typedef struct {
   int x;
   int y;
} Point;
Now, you do things that might look "wrong", like write a function that creates a point initialized from function arguments, and returns it, like so:
Point point_new(int x, int y)
{
  Point p;
  p.x = x;
  p.y = y;
  return p;
}
This is safe, as long (of course) as the return value is copied by value using struct assignment:
Point origin;
origin = point_new(0, 0);
In this way you can write quite clean and object-oriented-ish code, all in plain standard C.
 
 
*
C compilers implement one of several standards. However, having a standard does not mean that all aspects of the language are defined. Duff's device, for example, is a favorite 'hidden' feature that has become so popular that modern compilers have special purpose recognition code to ensure that optimization techniques do not clobber the desired effect of this often used pattern.
In general hidden features or language tricks are discouraged as you are running on the razor edge of whichever C standard(s) your compiler uses. Many such tricks do not work from one compiler to another, and often these kinds of features will fail from one version of a compiler suite by a given manufacturer to another version.
Various tricks that have broken C code include:
  1. Relying on how the compiler lays out structs in memory.
  2. Assumptions on endianness of integers/floats.
  3. Assumptions on function ABIs.
  4. Assumptions on the direction that stack frames grow.
  5. Assumptions about order of execution within statements.
  6. Assumptions about order of execution of statements in function arguments.
  7. Assumptions on the bit size or precision of short, int, long, float and double types.
Other problems and issues that arise whenever programmers make assumptions about execution models that are all specified in most C standards as 'compiler dependent' behavior.
 
 
*

When using sscanf you can use %n to find out where you should continue to read:
sscanf ( string, "%d%n", &number, &length );
string += length;
Apparently, you can't add another answer, so I'll include a second one here, you can use "&&" and "||" as conditionals:
#include <stdio.h>
#include <stdlib.h>

int main()
{
   1 || puts("Hello\n");
   0 || puts("Hi\n");
   1 && puts("ROFL\n");
   0 && puts("LOL\n");

   exit( 0 );
}
This code will output:
Hi
ROFL
 
*
Compile-time assumption-checking using enums: Stupid example, but can be really useful for libraries with compile-time configurable constants.
#define D 1
#define DD 2

enum CompileTimeCheck
{
    MAKE_SURE_DD_IS_TWICE_D = 1/(2*(D) == (DD)),
    MAKE_SURE_DD_IS_POW2    = 1/((((DD) - 1) & (DD)) == 0)
};
 
 
*

I discoverd recently 0 bitfields.
struct {
  int    a:3;
  int    b:2;
  int     :0;
  int    c:4;
  int    d:3;
};
which will give a layout of
000aaabb 0ccccddd
instead of without the :0;
0000aaab bccccddd
The 0 width field tells that the following bitfields should be set on the next atomic entity (char)
 
 
*
C99-style variable argument macros, aka
#define ERR(name, fmt, ...)   fprintf(stderr, "ERROR " #name ": " fmt "\n", \
                                  __VAR_ARGS__)
which would be used like
ERR(errCantOpen, "File %s cannot be opened", filename);
Here I also use the stringize operator and string constant concatentation, other features I really like.
 
*
Variable size automatic variables are also useful in some cases. These were added i nC99 and have been supported in gcc for a long time.
void foo(uint32_t extraPadding) {
    uint8_t commBuffer[sizeof(myProtocol_t) + extraPadding];
You end up with a buffer on the stack with room for the fixed-size protocol header plus variable size data. You can get the same effect with alloca(), but this syntax is more compact.
You have to make sure extraPadding is a reasonable value before calling this routine, or you end up blowing the stack. You'd have to sanity check the arguments before calling malloc or any other memory allocation technique, so this isn't really unusual.
 
 
*

In Visual Studio, it is possible for you to highlight your own defined types.
To do that, create a file called "usertype.dat" in the folder "Commom7/IDE". The contents of that file shall be the types you want to highlight. For example:
//content of usertype.dat
int8_t
int16_t
int32_t
int64_t
uint8_t
uint16_t
uint32_t
uint64_t
float32_t
float64_t
char_t
 
*
How about using while(0) inside a switch so you can use continue statements like break :-)
void sw(int s)
{
    switch (s) while (0) {
    case 0:
        printf("zero\n");
        continue;
    case 1:
        printf("one\n");
        continue;
    default:
        printf("something else\n");
        continue;
    }
}
 
 
*
The often forgotten %n specifier in printf format string can be quite practical sometimes. %n returns the current position of the imaginary cursor used when printf formats its output.
int pos1, pos2;
 char *string_of_unknown_length = "we don't care about the length of this";

  printf("Write text of unknown %n(%s)%n text\n", &pos1, string_of_unknown_length, &pos2);
  printf("%*s\\%*s/\n", pos1, " ", pos2-pos1-2, " ");
  printf("%*s", pos1+1, " ");
  for(int i=pos1+1; i<pos2-1; i++)
    putc('-', stdout);
  putc('\n', stdout);
will have following output
Write text of unknown (we don't care about the length of this) text
                      \                                      /
                       --------------------------------------
Granted a little bit contrived but can have some uses when making pretty reports.
 
 
*
Use NaN for chained calculations / error return :
//#include <stdint.h>
static uint64_t iNaN = 0xFFF8000000000000;
const double NaN = *(double *)&iNaN; // quiet NaN
An inner function can return NaN as an error flag : it can safely be used in any calculation, and the result will always be NaN.
note : testing for NaN is tricksy, since NaN != NaN... use isnan(x), or roll your own.
x!=x is mathematically correct if x is NaN, but tends to get optimised out by some compilers
 
 
*
I like the typeof() operator. It works like sizeof() in that it is resolved at compile time. Instead of returning the number of bytes, it returns the type. This is useful when you need to declare a variable to be the same type as some other variable, whatever type it may be.
typeof(foo) copy_of_foo; //declare bar to be a variable of the same type as foo
copy_of_foo = foo; //now copy_of_foo has a backup of foo, for any type
This might be just a gcc extension, I'm not sure.
 
 
*
Object oriented C macros: You need a constructor (init), a destructor (dispose), an equal (equal), a copier (copy), and some prototype for instantiation (prototype).
With the declaration, you need to declare a constant prototype to copy and derive from. Then you can do C_OO_NEW. I can post more examples if needed. LibPurple is a large object oriented C code base with a callback system (if you want to see one in use)
#define C_copy(to, from) to->copy(to, from)

#define true 1
#define false 0
#define C_OO_PROTOTYPE(type)\
void type##_init (struct type##_struct *my);\
void type##_dispose (struct type##_struct *my);\
char type##_equal (struct type##_struct *my, struct type##_struct *yours); \
struct type##_struct * type##_copy (struct type##_struct *my, struct type##_struct *from); \
const type type##__prototype = {type##_init, type##_dispose, type##_equal, type##_copy

#define C_OO_OVERHEAD(type)\
        void (*init) (struct type##_struct *my);\
        void (*dispose) (struct type##_struct *my);\
        char (*equal) (struct type##_struct *my, struct type##_struct *yours); \
        struct type##_struct *(*copy) (struct type##_struct *my, struct type##_struct *from); 

#define C_OO_IN(ret, type, function, ...)       ret (* function ) (struct type##_struct *my, __VA_ARGS__);
#define C_OO_OUT(ret, type, function, ...)      ret type##_##function (struct type##_struct *my, __VA_ARGS__);

#define C_OO_PNEW(type, instance)\
        instance = ( type *) malloc(sizeof( type ));\
        memcpy(instance, & type##__prototype, sizeof( type ));

#define C_OO_NEW(type, instance)\
        type instance;\
        memcpy(&instance, & type ## __prototype, sizeof(type));

#define C_OO_DELETE(instance)\
        instance->dispose(instance);\
        free(instance);

#define C_OO_INIT(type)         void type##_init (struct type##_struct *my){return;}
#define C_OO_DISPOSE(type)      void type##_dispose (struct type##_struct *my){return;}
#define C_OO_EQUAL(type)        char type##_equal (struct type##_struct *my, struct type##_struct *yours){return 0;}
#define C_OO_COPY(type)         struct type##_struct * type##_copy (struct type##_struct *my, struct type##_struct *from){return 0;}
 
 
 
 
 
*
Wrap malloc and realloc like this:
#ifdef _DEBUG
#define mmalloc(bytes)                  malloc(bytes);printf("malloc: %d\t<%s@%d>\n", bytes, __FILE__, __LINE__);
#define mrealloc(pointer, bytes)        realloc(pointer, bytes);printf("realloc: %d\t<%s@%d>\n", bytes, __FILE__, __LINE__);
#else //_DEBUG
#define mmalloc(bytes)                  malloc(bytes)
#define mrealloc(pointer, bytes)        realloc(pointer, bytes)
In fact, here is my full arsenol (The BailIfNot is for OO c):
#ifdef _DEBUG
#define mmalloc(bytes)                  malloc(bytes);printf("malloc: %d\t<%s@%d>\n", bytes, __FILE__, __LINE__);
#define mrealloc(pointer, bytes)        realloc(pointer, bytes);printf("realloc: %d\t<%s@%d>\n", bytes, __FILE__, __LINE__);
#define BAILIFNOT(Node, Check)  if(Node->type != Check) return 0;
#define NULLCHECK(var)          if(var == NULL) setError(__FILE__, __LINE__, "Null exception", " var ", FATAL);
#define ASSERT(n)               if( ! ( n ) ) { printf("<ASSERT FAILURE@%s:%d>", __FILE__, __LINE__); fflush(0); __asm("int $0x3"); }
#define TRACE(n)                printf("trace: %s <%s@%d>\n", n, __FILE__, __LINE__);fflush(0);
#else //_DEBUG
#define mmalloc(bytes)                  malloc(bytes)
#define mrealloc(pointer, bytes)        realloc(pointer, bytes)
#define BAILIFNOT(Node, Check)  {}
#define NULLCHECK(var)          {}
#define ASSERT(n)               {}
#define TRACE(n)                {}
#endif //_DEBUG
Here is some example output:
malloc: 12      <hash.c@298>
trace: nodeCreate <hash.c@302>
malloc: 5       <hash.c@308>
malloc: 16      <hash.c@316>
malloc: 256     <hash.c@320>
trace: dataLoadHead <hash.c@441>
malloc: 270     <hash.c@463>
malloc: 262144  <hash.c@467>
trace: dataLoadRecursive <hash.c@404>
 
 
 
 
*
Variable-sized structs, seen in common resolver libs among other places.
struct foo
{
  int a;
  int b;
  char b[1]; // using [0] is no longer correct
             // must come at end
};

char *str = "abcdef";
int len = strlen(str);
struct foo *bar = malloc(sizeof(foo) + len);

strcpy(bar.b, str); // try and stop me!
 
 
 
*
The size of function pointers is not standard. At least not in the K&R book. Even though it talks about size of other types of pointers but (I think) sizeof of a function pointer is undefined behavior.
Also sizeof is a compile time operator, I see a lot of people asking if sizeof is a function or an operator in online forums.
One error that I have seen is as follows (a simplified example):
int j;
int i;
j = sizeof(i++)
the increment on i would not be executed as sizeof is evaluated at compile time. The programmer intended to hack both operations, increment on i and calculation of sizeof in one statement.
Operator precedence in C governs order of association not order of evaluation. For example if you have three functions f,g,h each returning an int, and their is an expression like:
f() + g() * h()
C standard doesn't give rule about order of evaluation of these functions. Result of g and h would be multiplied before adding result of f. This can lead to error if the functions share state and computation depends on order of evaluation of these functions. This can lead to portability issues.
 
 
*
Here's three nice ones in gcc:
__FILE__ 
__FUNCTION__
__LINE__
 
 
*
Say you have a struct with members of the same type:
struct Point {
    float x;
    float y;
    float z;
};
You can cast instances of it to a float pointer and use array indices:
Point a;
int sum = 0, i = 0;
for( ; i < 3; i++)
    sum += ((float*)a)[i];
Pretty elementary, but useful when writing concise code.
 
 
*

register variables

I used to declare some variables with the register keyword to help speed things up. This would give a hint to the C compiler to use a CPU register as local storage. This is most likely no longer necessary as modern day C compilers do this automatically.
 
 
*
When comparing a variable to a literal, it is better to put the literal to the left of the == operator, to make the sure the compiler gives an error when you mistakenly use the assignment operator instead.
if (0 == count) {
    ...
}
Might look weird at first glance, but it could save some headache (like if you happened to type if (count = 0) by mistake).
 
 
*
Steve Webb has pointed out the __LINE__ and __FILE__ macros. It reminds me of how in my previous job I had hacked them to have in-memory logging.
I was working on a device where there was no port available to pass logging information from device to the PC being used for debugging. One could use breakpoints to halt and know the state of the program using debugger but there was no information on system trace.
Since all calls to debug logs were effectively a single global macro, we changed that macro to dump file name and line number on to a global array. This array contained series of file names and line numbers showing which debug calls were invoked, giving a fair idea of execution trace (not the actual log message though). One could pause the execution by debugger, dump these bytes onto a local file and then map this information to the code base using scripts. This was made possible because we had strict coding guidelines, so we could make had to make changes to the logging mechanism in one file.
 
 
*

intptr_t for declaring variables of type pointer. C99 specific and declared in stdint.h
 
 
*
Not really a hidden feature, but it looked to me like voodoo, the first time I saw something like this:

void callback(const char *msg, void *data)
{
    // do something with msg, e.g.
    printf("%s\n", msg);

    return;
    data = NULL;
}
The reason for this construction is, that if you compile this with -Wextra and without the "data = NULL;"-line, gcc will spit out a warning about unused parameters. But with this useless line you don't get a warning.
EDIT: I know there are other (better) ways to prevent those warnings. It just looked strange to me, the first time I saw this.
 
 
*
I only discovered this after 15+ years of C programming:
struct SomeStruct
{
   unsigned a : 5;
   unsigned b : 1;
   unsigned c : 7;
};
Bitfields! The number after the colon is the number of bits the member requires, with members packed into the specified type, so the above would look like the following if unsigned is 16 bits:
xxxc cccc ccba aaaa

Skizz
 
 
*
Conversion of types by using unusual typecasts. Though not hidden feature, its quite tricky.
Example:
If you needed to know how compiler stores float, just try this:
uint32_t Int;
float flt = 10.5; // say

Int = *(uint32_t *)&flt;

printf ("Float 10.5 is stored internally as %8X\n", Int);
or
float flt = 10.5; // say

printf ("Float 10.5 is stored internally as %8X\n", *(uint32_t *)&flt);
Note the clever use of typecasts. Converting address of variable (here &flt) to desired type (here (uint32_t * )) and extracting its content (applying '*').
This works other side of expression as well:
*(float *)&Int = flt;
This could also be accomplished using union:
typedef union
{
  uint32_t Int;
  float    flt;

} FloatInt_type;
 
 
 
*
I got shown this in a bit of code once, and asked what it did:

hexDigit = "0123456789abcdef"[someNybble];
Another favorite is:

unsigned char bar[100];
unsigned char *foo = bar;
unsigned char blah = 42[foo];
 
 
*
For clearing the input buffer you can't use fflush(stdin). The correct way is as follows: scanf("%*[^\n]%*c") This will discard everything from the input buffer.
 
 
*
Lambda's (e.g. anonymous functions) in GCC:
#define lambda(return_type, function_body) \
    ({ return_type fn function_body fn })
This can be used as:
lambda (int, (int x, int y) { return x > y; })(1, 2)
Which is expanded into:
({ int fn (int x, int y) { return x > y } fn; })(1, 2)
 
 
 
*

I liked the variable sized structures you could make:
typedef struct {
    unsigned int size;
    char buffer[1];
} tSizedBuffer;

tSizedBuffer *buff = (tSizedBuffer*)(malloc(sizeof(tSizedBuffer) + 99));

// can now refer to buff->buffer[0..99].
Also the offsetof macro which is now in ANSI C but was a piece of wizardry the first time I saw it. It basically uses the address-of operator (&) for a null pointer recast as a structure variable.
 
 
 
These all are copied from http://stackoverflow.com

Wednesday, 11 January 2017

DIFFERENCE BETWEEN RTOS and NON-OS IS

The main points of difference are as follows:

[Non-OS SDK]

The Non-OS SDK uses timers and callbacks as the main way to perform the various functions - nested events, functions triggered by certain conditions. The Non-OS SDK uses the espconn network interface; the user needs to develop their software according to the usage rules of the espconn interface.

[RTOS SDK]

1. RTOS version SDK uses the freeRTOS system, a multi-tasking OS. You can use standard interfaces to freeRTOS resource management, recycling operations, execution delay, inter-task messaging and synchronization, task-oriented process design. For the specifics of interface methods, refer to freeRTOS official website instructions or USING THE FREERTOS REAL TIME KERNEL - A Practical Guide introduction.

2. RTOS SDK version of the network operating interface is a standard lwIP API, while providing a package which enables BSD Socket APIsocket interface. Users can directly use the socket API to develop software applications; your code can also be directly compiled to run standard applications on other platforms Socket , effectively reducing the cost of learning platform switching. (possibly flawed translation)

3. RTOS version of the SDK introduces cJSON library, use the library functions to more easily parse JSON packets.

4. RTOS version is compatible with non-OS SDK in the Wi-Fi interface, smart config interfaces, Sniffer related interfaces, system interface, timer interface, FOTA interfaces and peripheral driver interface, but does not support the AT implementation.

Monday, 2 January 2017

Wifi Docs / Wireless Access Point

Introduction

In computer networking, a wireless access point (WAP) is a device that connects wireless communication devices together to form a wireless network. The WAP can connect to a wired or wireless network, relaying data between devices. There are several scenarios WAPs are used in:
  • Setup a home network.
  • Link together WAPs to form a larger network that allows clients to freely roam between without being disconnected.
  • Wireless client devices manage themselves in an ad-hoc network.

Setting up a wireless-to-wireless router

Overview

This is tested and geared to a home, or home office setup. It applies well to the following scenarios:
  • You don't want to have run ethernet cords all over the place.
  • your ISP restricts you to one IP address via a modem, a handful of IP addresses, or your ISP provides a wireless only router.
  • You want to avoid buying a load of additional, potentially expensive equipment.
The diagram for this:
                                                                 -> Android smartphone
                                                                /
[ISP Device] <----------> [WiFi Adapter][Computer][WiFi Adapter]--> Ubuntu/Mac/Windows Clients
                              (wlan1)                 (wlan0)   \
                                                                 -> iPhone

Prerequisites

  • Dedicated computer to be your router
  • Kubuntu Desktop 14.04.1 x64
  • wlan0 that supports being an access point. One may review what a card supports via a terminal:
    iw list
    * AP
    What was used in this test: Qualcomm Atheros AR9287 Wireless Network Adapter (PCI-Express) [168c:002e] (rev 01)
  • wlan1 that supports managed mode. One may review what a card supports via a terminal:
    iw list
    * Managed
    What was used in this test: Belkin N300 Wireless USB Adapter F9L1002v1 050d:845a
  • Wireless client device(s)
  • ISP provided wireless only router

Install Kubuntu

When installing, setup the initial user to automatically log in.

Setup hostapd, port forwarding, haveged, and dnsmasq

Install and configure hostapd to automatically start on boot up using wlan0, and communicate on 802.11n, 2.4GHz (150 Mbps), with WPA2-Personal:
sudo apt-get -y install hostapd
sudo nano /etc/default/hostapd
DAEMON_CONF="/etc/hostapd/hostapd.conf"
sudo nano /etc/hostapd/hostapd.conf
auth_algs=1
beacon_int=50
channel=3
country_code=US
disassoc_low_ack=1
driver=nl80211
hw_mode=g
ht_capab=[HT40+][HT40-][SHORT-GI-40][RX-STBC1]
ieee80211d=1
ieee80211n=1
interface=wlan0
require_ht=0
rsn_pairwise=CCMP
ssid=YOURSSID
wmm_enabled=1
wpa=2
wpa_key_mgmt=WPA-PSK
wpa_passphrase=YOURPASSPHASE
Replace the country_code, ssid, and wpa_passphrase with the applicable information. Warning /!\ For some reason, a Windows 8.1 client (Qualcomm Atheros AR956x Wireless Network Adapter) would not connect when require_ht=1. Event Viewer noted "A response was not received from the router or access point." However, this same client booted into Ubuntu worked fine, as well as Mac OS X Yosemite, iPhone, and a android smartphone.
Next, have port forwarding enabled automatically on boot up:
sudo nano /etc/sysctl.conf
net.ipv4.ip_forward=1
net.ipv6.conf.all.forwarding=1
Next, have NAT traffic initiated on wlan0 forwarded to wlan1 enabled automatically on boot up:
sudo nano /etc/rc.local
iptables -t nat -A POSTROUTING -o wlan1 -j MASQUERADE
iptables -A FORWARD -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT
iptables -A FORWARD -i wlan0 -o wlan1 -j ACCEPT
exit 0
Next, increase the default amount of entropy on your router and linux clients via haveged. Warning /!\ When a linux operating system runs low on entropy (< 1000), it causes severe encrypted communcation latency (among other problems):
sudo apt-get -y install haveged
Next, install and configure dnsmasq for DHCP mapping IP addresses to MAC addresses:
sudo apt-get -y install dnsmasq
sudo nano /etc/dnsmasq.conf
interface=wlan0
except-interface=wlan1
dhcp-range=10.0.0.2,10.0.0.14,12h
Note: One may want to setup DHCP reservations to bind a MAC address to a specific IP address (in the case of servers or clients you want to remote into by IP address) by adding to this file:
dhcp-host:XX:XX:XX:XX:XX,10.0.Y.Z
Where the "X"s are replaced with the MAC address, and both Y and Z with the relevant IP address numbers.

Configuring networking

One has a number of options for setting up networking. One may use the GUI driven NetworkManager for the managed interface and /etc/network/interfaces for access point. This has the benefit of being more user friendly. Another option is setting up both interfaces via /etc/network/interfaces. This has the benefit of reducing computer resources overhead.

Method 1: NetworkManager and /etc/network/interfaces

Connect wlan1 to the upstream router via NetworkManager (have "All users may connect to this network" checked). As well, it would be best to set the IP address statically so you may remote into this interface by IP address easily. It is recommended to setup x11vnc tunneled through SSH to easily administer the computer remotely.
Next, setup the wlan0 interface to have a static IP address, set to wireless master mode, and come up automatically on boot up via a terminal:
sudo nano /etc/network/interfaces
auto lo wlan0
iface lo inet loopback
#access point
iface wlan0 inet static
address 10.0.0.1
netmask 255.255.255.240
gateway 10.0.0.1
dns-nameservers 192.168.1.1
wireless-mode Master
Next, set NetworkManager to ignore the wlan0 interface:
sudo nano /etc/NetworkManager/NetworkManager.conf
[keyfile]
unmanaged-devices=mac:XX:XX:XX:XX:XX:XX
Replace the "X"s with the MAC address for wlan0.

Considerations

  • One may want to utilize a computer with two internal PCIe WiFi adapters, versus a USB WiFi dongle. This would maximize the speed of internal adapter-to-adapter communication, and avoid any potential USB overheat issues.
  • One would want to avoid using devices with less developed WiFi drivers (ex. Belkin N300 Wireless USB Adapter F9L1002v1 050d:845a which uses staging driver r8712u) over more developed ones (ex. ath9k). In the case of the above device with r8712u, this is due to how lowering the transmission power of the adapter via the following terminal command is not yet developed:
    iwconfig wlan0 txpower 14
  • While using a GUI eases administration, it incurs additional resource overhead to run it.

Setting up a bridged wireless-to-ethernet router

Overview

This is an advanced, command line only setup for creating a bridged wireless router with Ubuntu Server. Here is the network diagram for this setup:
WirelessAccessPointSetup.jpg
Note: This inkscape diagram network.svg is available for download from: More Actions > Attachments.

Prerequisites

  • One gigabit ethernet switch.
  • One USB drive with Ubuntu Server ISO setup for install (Verified with 7.10).
  • A dedicated computer that will function as your router, with the following hardware:
    • One wireless NIC (ath0), that supports master mode. For more on this, please see here.
    • One ethernet NICs (eth0).
  • Optional: A client computer to remotely configure your router. If your client is using Windows:

Install Ubuntu Server

Install Ubuntu Server Edition. One may choose the following options to install:
[*] DNS server
[*] OpenSSH server
Update and upgrade Ubuntu:
sudo apt-get update
sudo apt-get dist-upgrade
To install DNS server and SSH Server after an ubuntu installation use the command:
tasksel

Setup SSH

Assuming that your ubuntu box is connected to your upstream router, you will need to find your IP address of your ubuntu box so you can connect with putty:
ip addr
On your windows machine install putty. Type in your ubuntu IP address into putty then connect.You can now cut and paste the following the commands. If you want to transfer files use WinSCP.

Setup the network

eth0 is the WAN interface (gateway) eth1 is the LAN interface ath0 is the wireless card br0 is the bridged connection of ath0 and eth1
Setup bridging:
sudo apt-get install bridge-utils
Then edit the network config:
sudo nano /etc/network/interfaces
# This file describes the network interfaces available on your system
# and how to activate them. For more information, see interfaces(5).

# The loopback network interface
auto lo
iface lo inet loopback

#Gateway -
auto eth0
iface eth0 inet dhcp
pre-up iptables-restore < /etc/iptables.rules
post-down iptables-save > /etc/iptables.rules

#Wireless Setup
auto ath0
iface ath0 inet manual
wireless-mode master
wireless-essid pivotpoint

#Bridge interface
auto br0
iface br0 inet static
    address 10.1.1.1
    network 10.1.1.0
    netmask 255.255.255.0
    broadcast 10.1.1.255
    bridge-ports eth1 ath0

Setup firewall rules

Run these commands:
sudo iptables -t nat -A POSTROUTING -s 10.1.1.0/24 -o eth0 -j MASQUERADE
sudo iptables -A FORWARD -s 10.1.1.0/24 -o eth0 -j ACCEPT
sudo iptables -A FORWARD -d 10.1.1.0/24 -m conntrack --ctstate ESTABLISHED,RELATED -i eth0 -j ACCEPT
For logging add:
sudo iptables -A INPUT -m conntrack --ctstate NEW -p tcp --dport 80 -j LOG --log-prefix "NEW_HTTP_CONN: "
The above log will also appear in /var/log/messages, /var/log/syslog, and /var/log/kern.log.
Save to /etc/iptables.rules via:
sudo sh -c "iptables-save > /etc/iptables.rules"
NOTE: This is a basic setup that only routes NAT packets. Please investigate further securing your firewall.
Enable packet forwarding:
sudo nano /etc/sysctl.conf
Add the following line:
net.ipv4.ip_forward = 1

Diagnostic tools

Immediately allow the forwarding of packets. The configuration is not preserved on reboot but sets a flag in the kernel itself:
echo 1 | sudo tee /proc/sys/net/ipv4/ip_forward
Test the current setting of the kernel:
cat /proc/sys/net/ipv4/ip_forward
Note: The /proc directory is not on your hard drive but is present in the running kernel.

Setup the DHCP server

This will create a 10 machine DHCP server via a terminal:
sudo apt-get install dhcp3-server
Configure the server:
sudo nano /etc/dhcp3/dhcpd.conf
# Subnet for DHCP Clients
subnet 10.1.1.0 netmask 255.255.255.0 {
        option domain-name-servers 10.1.1.1;
        max-lease-time 7200;
        default-lease-time 600;
        range 10.1.1.50 10.1.1.60;
        option subnet-mask 255.255.255.0;
        option broadcast-address 10.1.1.255;
        option routers 10.1.1.1;
        }
NOTE: If a DNS server (bind9) hasn't been installed change "option domain-name-servers 10.1.1.1" to the IP address of the DNS server provided by your ISP. Optionally, one may use a public DNS server such as Google DNS: 8.8.8.8 or 8.8.4.4.
You also need to edit the file /etc/default/dhcp in order to specify the interfaces dhcpd should listen to. By default it listens to eth0. We need to only have it listen to our local NIC (br0):
sudo nano /etc/default/dhcp3-server
Then add:
INTERFACES="br0"
Restart.

Optional: Monitoring with darkstat

Stats with a http server:
sudo apt-get install darkstat
Edit the configuration file:
sudo nano /etc/darkstat/init.cfg
 # Turn this to yes when you have configured the options below.
START_DARKSTAT=yes

# Don't forget to read the man page.

# You must set this option, else darkstat may not listen to
# the interface you want
INTERFACE="-i eth1"

PORT="-p 8888"
#BINDIP="-b 127.0.0.1"
#LOCAL="-l 10.1.1.0/24"
#FIP="-f 127.0.0.1"
#DNS="-n"
#SPY="--spy eth1"
To see this point a browser to: http://10.1.1.1:8888

Optional: Monitoring with saidar

Saidar shows server usage:
sudo apt-get install saidar
then:
saidar

Optional: Disabling IPv6

Depending on your hardware, speed improvements may be found by disabling IPv6. For more on this, please see WebBrowsingSlowIPv6IPv4.

Backup

sudo su -
cd /
tar cvpjf backup.tar.bz2 --exclude=/proc --exclude=/media --exclude=/mnt --exclude=/dev --exclude=/lost+found --exclude=/backup.tar.bz2 --exclude=/tmp --exclude=/sys /
You will then have a tar ball that is your server.