/* LUFA Library Copyright (C) Dean Camera, 2017. dean [at] fourwalledcubicle [dot] com www.lufa-lib.org */ /* Copyright 2017 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 disclaims 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 * * Main source file for the MouseHostWithParser demo. This file contains the main tasks of * the demo and is responsible for the initial application hardware configuration. */ #include "MouseHostWithParser.h" /** Processed HID report descriptor items structure, containing information on each HID report element */ static HID_ReportInfo_t HIDReportInfo; /** LUFA HID Class driver interface configuration and state information. This structure is * passed to all HID Class driver functions, so that multiple instances of the same class * within a device can be differentiated from one another. */ USB_ClassInfo_HID_Host_t Mouse_HID_Interface = { .Config = { .DataINPipe = { .Address = (PIPE_DIR_IN | 1), .Banks = 1, }, .DataOUTPipe = { .Address = (PIPE_DIR_OUT | 2), .Banks = 1, }, .HIDInterfaceProtocol = HID_CSCP_NonBootProtocol, .HIDParserData = &HIDReportInfo }, }; /** Main program entry point. This routine configures the hardware required by the application, then * enters a loop to run the application tasks in sequence. */ int main(void) { SetupHardware(); puts_P(PSTR(ESC_FG_CYAN "Mouse Host Demo running.\r\n" ESC_FG_WHITE)); LEDs_SetAllLEDs(LEDMASK_USB_NOTREADY); GlobalInterruptEnable(); for (;;) { MouseHost_Task(); HID_Host_USBTask(&Mouse_HID_Interface); USB_USBTask(); } } /** Configures the board hardware and chip peripherals for the demo's functionality. */ void SetupHardware(void) { #if (ARCH == ARCH_AVR8) /* Disable watchdog if enabled by bootloader/fuses */ MCUSR &= ~(1 << WDRF); wdt_disable(); /* Disable clock division */ clock_prescale_set(clock_div_1); #endif /* Hardware Initialization */ Serial_Init(9600, false); LEDs_Init(); USB_Init(); /* Create a stdio stream for the serial port for stdin and stdout */ Serial_CreateStream(NULL); } /** Task to manage an enumerated USB mouse once connected, to display movement * data as it is received. */ void MouseHost_Task(void) { if (USB_HostState != HOST_STATE_Configured) return; if (HID_Host_IsReportReceived(&Mouse_HID_Interface)) { uint8_t MouseReport[Mouse_HID_Interface.State.LargestReportSize]; HID_Host_ReceiveReport(&Mouse_HID_Interface, &MouseReport); uint8_t LEDMask = LEDS_NO_LEDS; for (uint8_t ReportNumber = 0; ReportNumber < HIDReportInfo.TotalReportItems; ReportNumber++) { HID_ReportItem_t* ReportItem = &HIDReportInfo.ReportItems[ReportNumber]; /* Update the report item value if it is contained within the current report */ if (!(USB_GetHIDReportItemInfo(MouseReport, ReportItem))) continue; /* Determine what report item is being tested, process updated value as needed */ if ((ReportItem->Attributes.Usage.Page == USAGE_PAGE_BUTTON) && (ReportItem->ItemType == HID_REPORT_ITEM_In)) { /* Buttons are numbered sequentially in their HID usages, button 1 is the left mouse button */ uint8_t ButtonID = ReportItem->Attributes.Usage.Usage; if ((ButtonID == 1) && (ReportItem->Value != 0)) LEDMask = LEDS_ALL_LEDS; } else if ((ReportItem->Attributes.Usage.Page == USAGE_PAGE_GENERIC_DCTRL) && (ReportItem->Attributes.Usage.Usage == USAGE_SCROLL_WHEEL) && (ReportItem->ItemType == HID_REPORT_ITEM_In)) { /* Convert wheel data to a 16-bit signed value */ int16_t WheelDelta = HID_ALIGN_DATA(ReportItem, int16_t); if (WheelDelta) LEDMask = (LEDS_LED1 | LEDS_LED2 | ((WheelDelta > 0) ? LEDS_LED3 : LEDS_LED4)); } else if ((ReportItem->Attributes.Usage.Page == USAGE_PAGE_GENERIC_DCTRL) && ((ReportItem->Attributes.Usage.Usage == USAGE_X) || (ReportItem->Attributes.Usage.Usage == USAGE_Y)) && (ReportItem->ItemType == HID_REPORT_ITEM_In)) { /* Convert X/Y movement to 16-bit signed value */ int16_t DeltaMovement = HID_ALIGN_DATA(ReportItem, int16_t); if (DeltaMovement) { if (ReportItem->Attributes.Usage.Usage == USAGE_X) LEDMask |= ((DeltaMovement > 0) ? LEDS_LED1 : LEDS_LED2); else LEDMask |= ((DeltaMovement > 0) ? LEDS_LED3 : LEDS_LED4); } } } LEDs_SetAllLEDs(LEDMask); } } /** Event handler for the USB_DeviceAttached event. This indicates that a device has been attached to the host, and * starts the library USB task to begin the enumeration and USB management process. */ void EVENT_USB_Host_DeviceAttached(void) { puts_P(PSTR("Device Attached.\r\n")); LEDs_SetAllLEDs(LEDMASK_USB_ENUMERATING); } /** Event handler for the USB_DeviceUnattached event. This indicates that a device has been removed from the host, and * stops the library USB task management process. */ void EVENT_USB_Host_DeviceUnattached(void) { puts_P(PSTR("\r\nDevice Unattached.\r\n")); LEDs_SetAllLEDs(LEDMASK_USB_NOTREADY); } /** Event handler for the USB_DeviceEnumerationComplete event. This indicates that a device has been successfully * enumerated by the host and is now ready to be used by the application. */ void EVENT_USB_Host_DeviceEnumerationComplete(void) { LEDs_SetAllLEDs(LEDMASK_USB_ENUMERATING); uint16_t ConfigDescriptorSize; uint8_t ConfigDescriptorData[512]; if (USB_Host_GetDeviceConfigDescriptor(1, &ConfigDescriptorSize, ConfigDescriptorData, sizeof(ConfigDescriptorData)) != HOST_GETCONFIG_Successful) { puts_P(PSTR("Error Retrieving Configuration Descriptor.\r\n")); LEDs_SetAllLEDs(LEDMASK_USB_ERROR); return; } if (HID_Host_ConfigurePipes(&Mouse_HID_Interface, ConfigDescriptorSize, ConfigDescriptorData) != HID_ENUMERROR_NoError) { puts_P(PSTR("Attached Device Not a Valid Mouse.\r\n")); LEDs_SetAllLEDs(LEDMASK_USB_ERROR); return; } if (USB_Host_SetDeviceConfiguration(1) != HOST_SENDCONTROL_Successful) { puts_P(PSTR("Error Setting Device Configuration.\r\n")); LEDs_SetAllLEDs(LEDMASK_USB_ERROR); return; } if (HID_Host_SetReportProtocol(&Mouse_HID_Interface) != 0) { puts_P(PSTR("Error Setting Report Protocol Mode or Not a Valid Mouse.\r\n")); LEDs_SetAllLEDs(LEDMASK_USB_ERROR); USB_Host_SetDeviceConfiguration(0); return; } puts_P(PSTR("Mouse Enumerated.\r\n")); LEDs_SetAllLEDs(LEDMASK_USB_READY); } /** Event handler for the USB_HostError event. This indicates that a hardware error occurred while in host mode. */ void EVENT_USB_Host_HostError(const uint8_t ErrorCode) { USB_Disable(); printf_P(PSTR(ESC_FG_RED "Host Mode Error\r\n" " -- Error Code %d\r\n" ESC_FG_WHITE), ErrorCode); LEDs_SetAllLEDs(LEDMASK_USB_ERROR); for(;;); } /** Event handler for the USB_DeviceEnumerationFailed event. This indicates that a problem occurred while * enumerating an attached USB device. */ void EVENT_USB_Host_DeviceEnumerationFailed(const uint8_t ErrorCode, const uint8_t SubErrorCode) { printf_P(PSTR(ESC_FG_RED "Dev Enum Error\r\n" " -- Error Code %d\r\n" " -- Sub Error Code %d\r\n" " -- In State %d\r\n" ESC_FG_WHITE), ErrorCode, SubErrorCode, USB_HostState); LEDs_SetAllLEDs(LEDMASK_USB_ERROR); } /** Callback for the HID Report Parser. This function is called each time the HID report parser is about to store * an IN, OUT or FEATURE item into the HIDReportInfo structure. To save on RAM, we are able to filter out items * we aren't interested in (preventing us from being able to extract them later on, but saving on the RAM they would * have occupied). * * \param[in] CurrentItem Pointer to the item the HID report parser is currently working with * * \return Boolean \c true if the item should be stored into the HID report structure, \c false if it should be discarded */ bool CALLBACK_HIDParser_FilterHIDReportItem(HID_ReportItem_t* const CurrentItem) { bool IsMouse = false; /* Iterate through the item's collection path, until either the root collection node or a collection with the * Mouse Usage is found - this prevents Joysticks, which use identical descriptors except for the Joystick usage * parent node, from being erroneously treated as a mouse by the demo */ for (HID_CollectionPath_t* CurrPath = CurrentItem->CollectionPath; CurrPath != NULL; CurrPath = CurrPath->Parent) { if ((CurrPath->Usage.Page == USAGE_PAGE_GENERIC_DCTRL) && (CurrPath->Usage.Usage == USAGE_MOUSE)) { IsMouse = true; break; } } /* If a collection with the mouse usage was not found, indicate that we are not interested in this item */ if (!IsMouse) return false; /* Check the attributes of the current item - see if we are interested in it or not; * only store BUTTON and GENERIC_DESKTOP_CONTROL items into the Processed HID Report * structure to save RAM and ignore the rest */ return ((CurrentItem->Attributes.Usage.Page == USAGE_PAGE_BUTTON) || (CurrentItem->Attributes.Usage.Page == USAGE_PAGE_GENERIC_DCTRL)); } href='#n201'>201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624
Please send your questions to the
[googlemock](http://groups.google.com/group/googlemock) discussion
group. If you need help with compiler errors, make sure you have
tried [Google Mock Doctor](#How_am_I_supposed_to_make_sense_of_these_horrible_template_error.md) first.

## I wrote some matchers.  After I upgraded to a new version of Google Mock, they no longer compile.  What's going on? ##

After version 1.4.0 of Google Mock was released, we had an idea on how
to make it easier to write matchers that can generate informative
messages efficiently.  We experimented with this idea and liked what
we saw.  Therefore we decided to implement it.

Unfortunately, this means that if you have defined your own matchers
by implementing `MatcherInterface` or using `MakePolymorphicMatcher()`,
your definitions will no longer compile.  Matchers defined using the
`MATCHER*` family of macros are not affected.

Sorry for the hassle if your matchers are affected.  We believe it's
in everyone's long-term interest to make this change sooner than
later.  Fortunately, it's usually not hard to migrate an existing
matcher to the new API.  Here's what you need to do:

If you wrote your matcher like this:
```
// Old matcher definition that doesn't work with the latest
// Google Mock.
using ::testing::MatcherInterface;
...
class MyWonderfulMatcher : public MatcherInterface<MyType> {
 public:
  ...
  virtual bool Matches(MyType value) const {
    // Returns true if value matches.
    return value.GetFoo() > 5;
  }
  ...
};
```

you'll need to change it to:
```
// New matcher definition that works with the latest Google Mock.
using ::testing::MatcherInterface;
using ::testing::MatchResultListener;
...
class MyWonderfulMatcher : public MatcherInterface<MyType> {
 public:
  ...
  virtual bool MatchAndExplain(MyType value,
                               MatchResultListener* listener) const {
    // Returns true if value matches.
    return value.GetFoo() > 5;
  }
  ...
};
```
(i.e. rename `Matches()` to `MatchAndExplain()` and give it a second
argument of type `MatchResultListener*`.)

If you were also using `ExplainMatchResultTo()` to improve the matcher
message:
```
// Old matcher definition that doesn't work with the lastest
// Google Mock.
using ::testing::MatcherInterface;
...
class MyWonderfulMatcher : public MatcherInterface<MyType> {
 public:
  ...
  virtual bool Matches(MyType value) const {
    // Returns true if value matches.
    return value.GetFoo() > 5;
  }

  virtual void ExplainMatchResultTo(MyType value,
                                    ::std::ostream* os) const {
    // Prints some helpful information to os to help
    // a user understand why value matches (or doesn't match).
    *os << "the Foo property is " << value.GetFoo();
  }
  ...
};
```

you should move the logic of `ExplainMatchResultTo()` into
`MatchAndExplain()`, using the `MatchResultListener` argument where
the `::std::ostream` was used:
```
// New matcher definition that works with the latest Google Mock.
using ::testing::MatcherInterface;
using ::testing::MatchResultListener;
...
class MyWonderfulMatcher : public MatcherInterface<MyType> {
 public:
  ...
  virtual bool MatchAndExplain(MyType value,
                               MatchResultListener* listener) const {
    // Returns true if value matches.
    *listener << "the Foo property is " << value.GetFoo();
    return value.GetFoo() > 5;
  }
  ...
};
```

If your matcher is defined using `MakePolymorphicMatcher()`:
```
// Old matcher definition that doesn't work with the latest
// Google Mock.
using ::testing::MakePolymorphicMatcher;
...
class MyGreatMatcher {
 public:
  ...
  bool Matches(MyType value) const {
    // Returns true if value matches.
    return value.GetBar() < 42;
  }
  ...
};
... MakePolymorphicMatcher(MyGreatMatcher()) ...
```

you should rename the `Matches()` method to `MatchAndExplain()` and
add a `MatchResultListener*` argument (the same as what you need to do
for matchers defined by implementing `MatcherInterface`):
```
// New matcher definition that works with the latest Google Mock.
using ::testing::MakePolymorphicMatcher;
using ::testing::MatchResultListener;
...
class MyGreatMatcher {
 public:
  ...
  bool MatchAndExplain(MyType value,
                       MatchResultListener* listener) const {
    // Returns true if value matches.
    return value.GetBar() < 42;
  }
  ...
};
... MakePolymorphicMatcher(MyGreatMatcher()) ...
```

If your polymorphic matcher uses `ExplainMatchResultTo()` for better
failure messages:
```
// Old matcher definition that doesn't work with the latest
// Google Mock.
using ::testing::MakePolymorphicMatcher;
...
class MyGreatMatcher {
 public:
  ...
  bool Matches(MyType value) const {
    // Returns true if value matches.
    return value.GetBar() < 42;
  }
  ...
};
void ExplainMatchResultTo(const MyGreatMatcher& matcher,
                          MyType value,
                          ::std::ostream* os) {
  // Prints some helpful information to os to help
  // a user understand why value matches (or doesn't match).
  *os << "the Bar property is " << value.GetBar();
}
... MakePolymorphicMatcher(MyGreatMatcher()) ...
```

you'll need to move the logic inside `ExplainMatchResultTo()` to
`MatchAndExplain()`:
```
// New matcher definition that works with the latest Google Mock.
using ::testing::MakePolymorphicMatcher;
using ::testing::MatchResultListener;
...
class MyGreatMatcher {
 public:
  ...
  bool MatchAndExplain(MyType value,
                       MatchResultListener* listener) const {
    // Returns true if value matches.
    *listener << "the Bar property is " << value.GetBar();
    return value.GetBar() < 42;
  }
  ...
};
... MakePolymorphicMatcher(MyGreatMatcher()) ...
```

For more information, you can read these
[two](V1_5_CookBook#Writing_New_Monomorphic_Matchers.md)
[recipes](V1_5_CookBook#Writing_New_Polymorphic_Matchers.md)
from the cookbook.  As always, you
are welcome to post questions on `googlemock@googlegroups.com` if you
need any help.

## When using Google Mock, do I have to use Google Test as the testing framework?  I have my favorite testing framework and don't want to switch. ##

Google Mock works out of the box with Google Test.  However, it's easy
to configure it to work with any testing framework of your choice.
[Here](V1_5_ForDummies#Using_Google_Mock_with_Any_Testing_Framework.md) is how.

## How am I supposed to make sense of these horrible template errors? ##

If you are confused by the compiler errors gcc threw at you,
try consulting the _Google Mock Doctor_ tool first.  What it does is to
scan stdin for gcc error messages, and spit out diagnoses on the
problems (we call them diseases) your code has.

To "install", run command:
```
alias gmd='<path to googlemock>/scripts/gmock_doctor.py'
```

To use it, do:
```
<your-favorite-build-command> <your-test> 2>&1 | gmd
```

For example:
```
make my_test 2>&1 | gmd
```

Or you can run `gmd` and copy-n-paste gcc's error messages to it.

## Can I mock a variadic function? ##

You cannot mock a variadic function (i.e. a function taking ellipsis
(`...`) arguments) directly in Google Mock.

The problem is that in general, there is _no way_ for a mock object to
know how many arguments are passed to the variadic method, and what
the arguments' types are.  Only the _author of the base class_ knows
the protocol, and we cannot look into his head.

Therefore, to mock such a function, the _user_ must teach the mock
object how to figure out the number of arguments and their types.  One
way to do it is to provide overloaded versions of the function.

Ellipsis arguments are inherited from C and not really a C++ feature.
They are unsafe to use and don't work with arguments that have
constructors or destructors.  Therefore we recommend to avoid them in
C++ as much as possible.

## MSVC gives me warning C4301 or C4373 when I define a mock method with a const parameter.  Why? ##

If you compile this using Microsoft Visual C++ 2005 SP1:
```
class Foo {
  ...
  virtual void Bar(const int i) = 0;
};

class MockFoo : public Foo {
  ...
  MOCK_METHOD1(Bar, void(const int i));
};
```
You may get the following warning:
```
warning C4301: 'MockFoo::Bar': overriding virtual function only differs from 'Foo::Bar' by const/volatile qualifier
```

This is a MSVC bug.  The same code compiles fine with gcc ,for
example.  If you use Visual C++ 2008 SP1, you would get the warning:
```
warning C4373: 'MockFoo::Bar': virtual function overrides 'Foo::Bar', previous versions of the compiler did not override when parameters only differed by const/volatile qualifiers
```

In C++, if you _declare_ a function with a `const` parameter, the
`const` modifier is _ignored_.  Therefore, the `Foo` base class above
is equivalent to:
```
class Foo {
  ...
  virtual void Bar(int i) = 0;  // int or const int?  Makes no difference.
};
```

In fact, you can _declare_ Bar() with an `int` parameter, and _define_
it with a `const int` parameter.  The compiler will still match them
up.

Since making a parameter `const` is meaningless in the method
_declaration_, we recommend to remove it in both `Foo` and `MockFoo`.
That should workaround the VC bug.

Note that we are talking about the _top-level_ `const` modifier here.
If the function parameter is passed by pointer or reference, declaring
the _pointee_ or _referee_ as `const` is still meaningful.  For
example, the following two declarations are _not_ equivalent:
```
void Bar(int* p);        // Neither p nor *p is const.
void Bar(const int* p);  // p is not const, but *p is.
```

## I have a huge mock class, and Microsoft Visual C++ runs out of memory when compiling it.  What can I do? ##

We've noticed that when the `/clr` compiler flag is used, Visual C++
uses 5~6 times as much memory when compiling a mock class.  We suggest
to avoid `/clr` when compiling native C++ mocks.

## I can't figure out why Google Mock thinks my expectations are not satisfied.  What should I do? ##

You might want to run your test with
`--gmock_verbose=info`.  This flag lets Google Mock print a trace
of every mock function call it receives.  By studying the trace,
you'll gain insights on why the expectations you set are not met.

## How can I assert that a function is NEVER called? ##

```
EXPECT_CALL(foo, Bar(_))
    .Times(0);
```

## I have a failed test where Google Mock tells me TWICE that a particular expectation is not satisfied.  Isn't this redundant? ##

When Google Mock detects a failure, it prints relevant information
(the mock function arguments, the state of relevant expectations, and
etc) to help the user debug.  If another failure is detected, Google
Mock will do the same, including printing the state of relevant
expectations.

Sometimes an expectation's state didn't change between two failures,
and you'll see the same description of the state twice.  They are
however _not_ redundant, as they refer to _different points in time_.
The fact they are the same _is_ interesting information.

## I get a heap check failure when using a mock object, but using a real object is fine.  What can be wrong? ##

Does the class (hopefully a pure interface) you are mocking have a
virtual destructor?

Whenever you derive from a base class, make sure its destructor is
virtual.  Otherwise Bad Things will happen.  Consider the following
code:

```
class Base {
 public:
  // Not virtual, but should be.
  ~Base() { ... }
  ...
};

class Derived : public Base {
 public:
  ...
 private:
  std::string value_;
};

...
  Base* p = new Derived;
  ...
  delete p;  // Surprise! ~Base() will be called, but ~Derived() will not
             // - value_ is leaked.
```

By changing `~Base()` to virtual, `~Derived()` will be correctly
called when `delete p` is executed, and the heap checker
will be happy.

## The "newer expectations override older ones" rule makes writing expectations awkward.  Why does Google Mock do that? ##

When people complain about this, often they are referring to code like:

```
// foo.Bar() should be called twice, return 1 the first time, and return
// 2 the second time.  However, I have to write the expectations in the
// reverse order.  This sucks big time!!!
EXPECT_CALL(foo, Bar())
    .WillOnce(Return(2))
    .RetiresOnSaturation();
EXPECT_CALL(foo, Bar())
    .WillOnce(Return(1))
    .RetiresOnSaturation();
```

The problem is that they didn't pick the **best** way to express the test's
intent.

By default, expectations don't have to be matched in _any_ particular
order.  If you want them to match in a certain order, you need to be
explicit.  This is Google Mock's (and jMock's) fundamental philosophy: it's
easy to accidentally over-specify your tests, and we want to make it
harder to do so.

There are two better ways to write the test spec.  You could either
put the expectations in sequence:

```
// foo.Bar() should be called twice, return 1 the first time, and return
// 2 the second time.  Using a sequence, we can write the expectations
// in their natural order.
{
  InSequence s;
  EXPECT_CALL(foo, Bar())
      .WillOnce(Return(1))
      .RetiresOnSaturation();