aboutsummaryrefslogtreecommitdiffstats
path: root/Projects/Webserver/Lib/DHCPClientApp.h
blob: e305f932abe99dbbe2f84bd8912a173cbfb4755f (plain)
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
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
/*
             LUFA Library
     Copyright (C) Dean Camera, 2010.

  dean [at] fourwalledcubicle [dot] com
      www.fourwalledcubicle.com
*/

/*
  Copyright 2010  Dean Camera (dean [at] fourwalledcubicle [dot] com)

  Permission to use, copy, modify, distribute, and sell this
  software and its documentation for any purpose is hereby granted
  without fee, provided that the above copyright notice appear in
  all copies and that both that the copyright notice and this
  permission notice and warranty disclaimer appear in supporting
  documentation, and that the name of the author not be used in
  advertising or publicity pertaining to distribution of the
  software without specific, written prior permission.

  The author disclaim all warranties with regard to this
  software, including all implied warranties of merchantability
  and fitness.  In no event shall the author be liable for any
  special, indirect or consequential damages or any damages
  whatsoever resulting from loss of use, data or profits, whether
  in an action of contract, negligence or other tortious action,
  arising out of or in connection with the use or performance of
  this software.
*/

/** \file
 *
 *  Header file for DHCPClientApp.c.
 */

#ifndef _DHCPCLIENT_APP_H_
#define _DHCPCLIENT_APP_H_

	/* Includes: */
		#include <stdio.h>

		#include <uip.h>

		#include "../Webserver.h"

	/* Macros: */
		/** UDP listen port for a BOOTP server. */
		#define DHCPC_SERVER_PORT         67

		/** UDP listen port for a BOOTP client. */
		#define DHCPC_CLIENT_PORT         68

		/** BOOTP message type for a BOOTP REQUEST message. */
		#define DHCP_OP_BOOTREQUEST       0x01

		/** BOOTP message type for a BOOTP REPLY message. */
		#define DHCP_OP_BOOTREPLY         0x02

		/** BOOTP flag for a BOOTP broadcast message. */
		#define BOOTP_BROADCAST           0x8000

		/** Magic DHCP cookie for a BOOTP message to identify it as a DHCP message. */
		#define DHCP_MAGIC_COOKIE         0x63538263

		/** Unique transaction ID used to identify DHCP responses to the client. */
		#define DHCP_TRANSACTION_ID       0x13245466

		/** DHCP message type for a DISCOVER message. */
		#define DHCP_DISCOVER             1

		/** DHCP message type for an OFFER message. */
		#define DHCP_OFFER                2

		/** DHCP message type for a REQUEST message. */
		#define DHCP_REQUEST              3

		/** DHCP message type for a DECLINE message. */
		#define DHCP_DECLINE              4

		/** DHCP message type for an ACK message. */
		#define DHCP_ACK                  5

		/** DHCP message type for a NAK message. */
		#define DHCP_NAK                  6

		/** DHCP message type for a RELEASE message. */
		#define DHCP_RELEASE              7

		/** DHCP medium type for standard Ethernet. */
		#define DHCP_HTYPE_ETHERNET       1

		/** DHCP message option for the network subnet mask. */
		#define DHCP_OPTION_SUBNET_MASK   1

		/** DHCP message option for the network gateway IP. */
		#define DHCP_OPTION_ROUTER        3

		/** DHCP message option for the network DNS server. */
		#define DHCP_OPTION_DNS_SERVER    6

		/** DHCP message option for the requested client IP address. */
		#define DHCP_OPTION_REQ_IPADDR    50

		/** DHCP message option for the IP address lease time. */
		#define DHCP_OPTION_LEASE_TIME    51

		/** DHCP message option for the DHCP message type. */
		#define DHCP_OPTION_MSG_TYPE      53

		/** DHCP message option for the DHCP server IP. */
		#define DHCP_OPTION_SERVER_ID     54

		/** DHCP message option for the list of required options from the server. */
		#define DHCP_OPTION_REQ_LIST      55

		/** DHCP message option for the options list terminator. */
		#define DHCP_OPTION_END           255

	/* Type Defines: */
		/** Type define for a DHCP packet inside an Ethernet frame. */
		typedef struct
		{
			uint8_t  Operation; /**< DHCP operation, either DHCP_OP_BOOTREQUEST or DHCP_OP_BOOTREPLY */
			uint8_t  HardwareType; /**< Hardware carrier type constant */
			uint8_t  HardwareAddressLength;  /**< Length in bytes of a hardware (MAC) address on the network */
			uint8_t  Hops; /**< Number of hops required to reach the server, unused */

			uint32_t TransactionID; /**< Unique ID of the DHCP packet, for positive matching between sent and received packets */

			uint16_t ElapsedSeconds; /**< Elapsed seconds since the request was made */
			uint16_t Flags; /**< BOOTP packet flags */

			uip_ipaddr_t ClientIP; /**< Client IP address, if already leased an IP */
			uip_ipaddr_t YourIP; /**< Client IP address */
			uip_ipaddr_t NextServerIP; /**< Legacy BOOTP protocol field, unused for DHCP */
			uip_ipaddr_t RelayAgentIP; /**< Legacy BOOTP protocol field, unused for DHCP */

			uint8_t ClientHardwareAddress[16]; /**< Hardware (MAC) address of the client making a request to the DHCP server */
			uint8_t ServerHostnameString[64]; /**< Legacy BOOTP protocol field, unused for DHCP */
			uint8_t BootFileName[128]; /**< Legacy BOOTP protocol field, unused for DHCP */

			uint32_t Cookie; /**< Magic BOOTP protocol cookie to indicate a valid packet */

			uint8_t  Options[]; /**< DHCP message options */
		} DHCP_Header_t;

	/* Enums: */
		/** States for each DHCP connection to a DHCP client. */
		enum DHCP_States_t
		{
			DHCP_STATE_SendDiscover,  /**< Send DISCOVER packet to retrieve DHCP lease offers */
			DHCP_STATE_WaitForOffer,  /**< Waiting for OFFER packet giving available DHCP leases */
			DHCP_STATE_SendRequest,   /**< Send REQUEST packet to request a DHCP lease */
			DHCP_STATE_WaitForACK,    /**< Wait for ACK packet to complete the DHCP lease */
			DHCP_STATE_AddressLeased, /**< DHCP address has been leased from a DHCP server */
		};

	/* Function Prototypes: */
		void DHCPClientApp_Init(void);
		void DHCPClientApp_Callback(void);

		#if defined(INCLUDE_FROM_DHCPCLIENTAPP_C)
			static uint16_t DHCPClientApp_FillDHCPHeader(DHCP_Header_t* const DHCPHeader,
			                                             const uint8_t DHCPMessageType,
			                                             uip_udp_appstate_t* const AppState);
			static uint8_t  DHCPClientApp_SetOption(uint8_t* DHCPOptionList,
			                                        const uint8_t Option,
			                                        const uint8_t DataLen,
			                                        void* const OptionData);
			static bool     DHCPClientApp_GetOption(const uint8_t* DHCPOptionList,
			                                        const uint8_t Option,
			                                        void* const Destination);
		#endif
#endif
t: bold } /* Name.Function.Magic */ .highlight .vc { color: #336699 } /* Name.Variable.Class */ .highlight .vg { color: #dd7700 } /* Name.Variable.Global */ .highlight .vi { color: #3333bb } /* Name.Variable.Instance */ .highlight .vm { color: #336699 } /* Name.Variable.Magic */ .highlight .il { color: #0000DD; font-weight: bold } /* Literal.Number.Integer.Long */
# Defining a Mock Class #

## Mocking a Normal Class ##

Given
```
class Foo {
  ...
  virtual ~Foo();
  virtual int GetSize() const = 0;
  virtual string Describe(const char* name) = 0;
  virtual string Describe(int type) = 0;
  virtual bool Process(Bar elem, int count) = 0;
};
```
(note that `~Foo()` **must** be virtual) we can define its mock as
```
#include "gmock/gmock.h"

class MockFoo : public Foo {
  MOCK_CONST_METHOD0(GetSize, int());
  MOCK_METHOD1(Describe, string(const char* name));
  MOCK_METHOD1(Describe, string(int type));
  MOCK_METHOD2(Process, bool(Bar elem, int count));
};
```

To create a "nice" mock object which ignores all uninteresting calls,
or a "strict" mock object, which treats them as failures:
```
NiceMock<MockFoo> nice_foo;     // The type is a subclass of MockFoo.
StrictMock<MockFoo> strict_foo; // The type is a subclass of MockFoo.
```

## Mocking a Class Template ##

To mock
```
template <typename Elem>
class StackInterface {
 public:
  ...
  virtual ~StackInterface();
  virtual int GetSize() const = 0;
  virtual void Push(const Elem& x) = 0;
};
```
(note that `~StackInterface()` **must** be virtual) just append `_T` to the `MOCK_*` macros:
```
template <typename Elem>
class MockStack : public StackInterface<Elem> {
 public:
  ...
  MOCK_CONST_METHOD0_T(GetSize, int());
  MOCK_METHOD1_T(Push, void(const Elem& x));
};
```

## Specifying Calling Conventions for Mock Functions ##

If your mock function doesn't use the default calling convention, you
can specify it by appending `_WITH_CALLTYPE` to any of the macros
described in the previous two sections and supplying the calling
convention as the first argument to the macro. For example,
```
  MOCK_METHOD_1_WITH_CALLTYPE(STDMETHODCALLTYPE, Foo, bool(int n));
  MOCK_CONST_METHOD2_WITH_CALLTYPE(STDMETHODCALLTYPE, Bar, int(double x, double y));
```
where `STDMETHODCALLTYPE` is defined by `<objbase.h>` on Windows.

# Using Mocks in Tests #

The typical flow is:
  1. Import the Google Mock names you need to use. All Google Mock names are in the `testing` namespace unless they are macros or otherwise noted.
  1. Create the mock objects.
  1. Optionally, set the default actions of the mock objects.
  1. Set your expectations on the mock objects (How will they be called? What wil they do?).
  1. Exercise code that uses the mock objects; if necessary, check the result using [Google Test](http://code.google.com/p/googletest/) assertions.
  1. When a mock objects is destructed, Google Mock automatically verifies that all expectations on it have been satisfied.

Here is an example:
```
using ::testing::Return;                            // #1

TEST(BarTest, DoesThis) {
  MockFoo foo;                                    // #2

  ON_CALL(foo, GetSize())                         // #3
      .WillByDefault(Return(1));
  // ... other default actions ...

  EXPECT_CALL(foo, Describe(5))                   // #4
      .Times(3)
      .WillRepeatedly(Return("Category 5"));
  // ... other expectations ...

  EXPECT_EQ("good", MyProductionFunction(&foo));  // #5
}                                                 // #6
```

# Setting Default Actions #

Google Mock has a **built-in default action** for any function that
returns `void`, `bool`, a numeric value, or a pointer.

To customize the default action for functions with return type `T` globally:
```
using ::testing::DefaultValue;

DefaultValue<T>::Set(value);  // Sets the default value to be returned.
// ... use the mocks ...
DefaultValue<T>::Clear();     // Resets the default value.
```

To customize the default action for a particular method, use `ON_CALL()`:
```
ON_CALL(mock_object, method(matchers))
    .With(multi_argument_matcher)  ?
    .WillByDefault(action);
```

# Setting Expectations #

`EXPECT_CALL()` sets **expectations** on a mock method (How will it be
called? What will it do?):
```
EXPECT_CALL(mock_object, method(matchers))
    .With(multi_argument_matcher)  ?
    .Times(cardinality)            ?
    .InSequence(sequences)         *
    .After(expectations)           *
    .WillOnce(action)              *
    .WillRepeatedly(action)        ?
    .RetiresOnSaturation();        ?
```

If `Times()` is omitted, the cardinality is assumed to be:

  * `Times(1)` when there is neither `WillOnce()` nor `WillRepeatedly()`;
  * `Times(n)` when there are `n WillOnce()`s but no `WillRepeatedly()`, where `n` >= 1; or
  * `Times(AtLeast(n))` when there are `n WillOnce()`s and a `WillRepeatedly()`, where `n` >= 0.

A method with no `EXPECT_CALL()` is free to be invoked _any number of times_, and the default action will be taken each time.

# Matchers #

A **matcher** matches a _single_ argument.  You can use it inside
`ON_CALL()` or `EXPECT_CALL()`, or use it to validate a value
directly:

| `EXPECT_THAT(value, matcher)` | Asserts that `value` matches `matcher`. |
|:------------------------------|:----------------------------------------|
| `ASSERT_THAT(value, matcher)` | The same as `EXPECT_THAT(value, matcher)`, except that it generates a **fatal** failure. |

Built-in matchers (where `argument` is the function argument) are
divided into several categories:

## Wildcard ##
|`_`|`argument` can be any value of the correct type.|
|:--|:-----------------------------------------------|
|`A<type>()` or `An<type>()`|`argument` can be any value of type `type`.     |

## Generic Comparison ##

|`Eq(value)` or `value`|`argument == value`|
|:---------------------|:------------------|
|`Ge(value)`           |`argument >= value`|
|`Gt(value)`           |`argument > value` |
|`Le(value)`           |`argument <= value`|
|`Lt(value)`           |`argument < value` |
|`Ne(value)`           |`argument != value`|
|`IsNull()`            |`argument` is a `NULL` pointer (raw or smart).|
|`NotNull()`           |`argument` is a non-null pointer (raw or smart).|
|`Ref(variable)`       |`argument` is a reference to `variable`.|
|`TypedEq<type>(value)`|`argument` has type `type` and is equal to `value`. You may need to use this instead of `Eq(value)` when the mock function is overloaded.|

Except `Ref()`, these matchers make a _copy_ of `value` in case it's
modified or destructed later. If the compiler complains that `value`
doesn't have a public copy constructor, try wrap it in `ByRef()`,
e.g. `Eq(ByRef(non_copyable_value))`. If you do that, make sure
`non_copyable_value` is not changed afterwards, or the meaning of your
matcher will be changed.

## Floating-Point Matchers ##

|`DoubleEq(a_double)`|`argument` is a `double` value approximately equal to `a_double`, treating two NaNs as unequal.|
|:-------------------|:----------------------------------------------------------------------------------------------|
|`FloatEq(a_float)`  |`argument` is a `float` value approximately equal to `a_float`, treating two NaNs as unequal.  |
|`NanSensitiveDoubleEq(a_double)`|`argument` is a `double` value approximately equal to `a_double`, treating two NaNs as equal.  |
|`NanSensitiveFloatEq(a_float)`|`argument` is a `float` value approximately equal to `a_float`, treating two NaNs as equal.    |