--- rstp.h.orig	2012-12-21 09:24:35.492806900 -0500
+++ rstp.h	2012-12-21 09:24:45.710741400 -0500
@@ -222,6 +222,7 @@
 void *STP_OUT_mem_zalloc(unsigned int size);
 
 void STP_OUT_mem_free(void *);
+int STP_OUT_topologychanged(int setOrRead);
 
 
 
@@ -232,6 +233,10 @@
 #define COMPILER_INLINE_PACK  __packed__
 #elif defined (__ICCARM__)
 #define COMPILER_INLINE_PACK
+#elif defined WIN32
+#define COMPILER_INLINE_PACK
+#elif defined WINCE
+#define COMPILER_INLINE_PACK
 #else
 DEFINE PACKING FOR YOUR COMPILER
 #endif
--- rstp.c.orig	2012-12-21 09:27:38.374409000 -0500
+++ rstp.c	2012-12-21 09:27:53.053914900 -0500
@@ -28,11 +28,21 @@
   Section references in the code refer to those parts of the standard.
 *********************************************************************/
 
+/* Changes: 
+23 MAY 12: 
+    renamed WINCE_BUILD, STP_DEBUG_PRINT, STP_ERROR_PRINT, and STP_ABORT macros
+    added STP_ERROR_PRINT_NO_REFS macro to avoid dereference of uninitialized pointers (bug in original code)
+*/
+
 #include "rstp.h"
 #include <string.h>
 
-/* Macros to be used in the later parts */
+#ifdef WINCE_BUILD
+    #pragma warning(disable: 4127 4244 4100 4389 4245 4700)
+    #define inline
+#endif
 
+/* Macros to be used in the later parts */
 
 #ifndef NULL
 #define NULL ((void *)0)
@@ -107,19 +117,21 @@
 
 /* Logging macros */
 #ifndef __GNUC__
-#define DEBUG(...) \
+#define STP_DEBUG_PRINT(...) \
   STP_OUT_logmsg(BRIDGE->user_ref, PORT->user_ref, STP_LOG_LEVEL_DEBUG, __VA_ARGS__)
-#define ERROR(...) \
+#define STP_ERROR_PRINT(...) \
   STP_OUT_logmsg(BRIDGE->user_ref, PORT->user_ref, STP_LOG_LEVEL_ERROR, __VA_ARGS__)
-#define ABORT(...) \
-  { ERROR(__VA_ARGS__);}
+#define STP_ERROR_PRINT_NO_REFS(...) \
+  STP_OUT_logmsg(NULL, NULL, STP_LOG_LEVEL_ERROR, __VA_ARGS__)
+#define STP_ABORT(...) \
+  { STP_ERROR_PRINT(__VA_ARGS__);}
 #else
-#define DEBUG(fmt...) \
+#define STP_DEBUG_PRINT(fmt...) \
   STP_OUT_logmsg(BRIDGE->user_ref, PORT->user_ref, STP_LOG_LEVEL_DEBUG, fmt)
-#define ERROR(fmt...) \
+#define STP_ERROR_PRINT(fmt...) \
   STP_OUT_logmsg(BRIDGE->user_ref, PORT->user_ref, STP_LOG_LEVEL_ERROR, fmt)
-#define ABORT(fmt...) \
-  ({ ERROR(fmt); *(int *)0 = 1; })
+#define STP_ABORT(fmt...) \
+  ({ STP_ERROR_PRINT(fmt); *(int *)0 = 1; })
 #endif
 
 /***************** Macros for state machine descriptions ********************/
@@ -151,7 +163,7 @@
 {                                                                           \
   if (_cond) {                                                               \
     new_state = STN(_new_state);                                             \
-    DEBUG("%s: Transition to state %s\n", _STR(STM_NAME), #_new_state);      \
+    STP_DEBUG_PRINT("%s: Transition to state %s\n", _STR(STM_NAME), #_new_state);      \
     goto STM_LABEL(_new_state);                                              \
   }                                                                          \
 }
@@ -160,7 +172,7 @@
 ({                                                                           \
   if (_cond) {                                                               \
     new_state = STN(_new_state);                                             \
-    DEBUG("%s: Transition to state %s\n", _STR(STM_NAME), #_new_state);      \
+    STP_DEBUG_PRINT("%s: Transition to state %s\n", _STR(STM_NAME), #_new_state);      \
     goto STM_LABEL(_new_state);                                              \
   }                                                                          \
 })
@@ -189,13 +201,13 @@
 #define BG(...)                                              \
          case STN(BEGIN):                                                \
              __VA_ARGS__                                                \
-             ABORT("%s: No where to go from BEGIN\n", _STR(STM_NAME));   \
+             STP_ABORT("%s: No where to go from BEGIN\n", _STR(STM_NAME));   \
              return -1
 #else
 #define BG(_transitions...)                                              \
          case STN(BEGIN):                                                \
              _transitions                                                \
-             ABORT("%s: No where to go from BEGIN\n", _STR(STM_NAME));   \
+             STP_ABORT("%s: No where to go from BEGIN\n", _STR(STM_NAME));   \
              return -1
 #endif
 
@@ -221,6 +233,12 @@
 /* This just barely works. _args expansion includes commas */
 //int STM_FUNC(STM_NAME)(int state, int single_step, _args)
 
+#ifdef WINCE_BUILD
+    #define FUNC __FUNCTION__
+#else
+    #define FUNC __func__
+#endif
+
 #ifndef __GNUC__
 #define STM(_args, ...)                                 \
 static STM_FUNC_DECL(STM_FUNC(STM_NAME), _args)                  \
@@ -229,7 +247,7 @@
   switch (state) {                                               \
     __VA_ARGS__                                                  \
       default:                                                   \
-    ABORT("%s: Got unknown state %d\n", __func__, state);        \
+    STP_ABORT("%s: Got unknown state %d\n", FUNC, state);        \
     return -1;                                                   \
   }                                                              \
 }
@@ -241,7 +259,7 @@
   switch (state) {                                               \
     _contents                                                    \
       default:                                                   \
-    ABORT("%s: Got unknown state %d\n", __func__, state);        \
+    STP_ABORT("%s: Got unknown state %d\n", FUNC, state);        \
     return -1;                                                   \
   }                                                              \
 }
@@ -295,32 +313,31 @@
 
 typedef uint bool;
 
-#ifdef __ICCARM__
-#pragma pack(1)
-#endif
+#if defined(__ICCARM__) || defined(WINCE_BUILD)
+#pragma pack(1)
+#endif
 typedef COMPILER_INLINE_PACK struct _BridgeId {
   uchar bridge_identifier_priority[2];
   uchar bridge_address[6];
 } __attribute__((packed)) BridgeId;
-#ifdef __ICCARM__
-#pragma pack()
-#endif
-
-#ifdef __ICCARM__
-#pragma pack(1)
-#endif
+#if defined(__ICCARM__) || defined(WINCE_BUILD)
+#pragma pack()
+#endif
+
+#if defined(__ICCARM__) || defined(WINCE_BUILD)
+#pragma pack(1)
+#endif
 typedef COMPILER_INLINE_PACK struct _PathCost{
   uchar cost[4];
 } __attribute__((packed)) PathCost;
-#ifdef __ICCARM__
-#pragma pack()
-#endif
+#if defined(__ICCARM__) || defined(WINCE_BUILD)
+#pragma pack()
+#endif
 
 static inline uint path_cost_to_uint(PathCost x)
 {
   return
     (x.cost[0] << 24) + (x.cost[1] << 16) + (x.cost[2] << 8) + (x.cost[3]);
-
 }
 
 #ifndef __GNUC__
@@ -355,24 +372,24 @@
 
 #endif
 
-#ifdef __ICCARM__
-#pragma pack(1)
-#endif
+#if defined(__ICCARM__) || defined(WINCE_BUILD)
+#pragma pack(1)
+#endif
 typedef COMPILER_INLINE_PACK struct _PortId {
   uchar port_id[2]; /* 4 high bits of priority and 12 for Id */
 } __attribute__((packed)) PortId;
-#ifdef __ICCARM__
-#pragma pack()
-#endif
+#if defined(__ICCARM__) || defined(WINCE_BUILD)
+#pragma pack()
+#endif
 
 static inline uint port_id_to_uint(PortId p)
 {
   return (p.port_id[0] << 8) + p.port_id[1];
 }
 
-#ifdef __ICCARM__
-#pragma pack(1)
-#endif
+#if defined(__ICCARM__) || defined(WINCE_BUILD)
+#pragma pack(1)
+#endif
 typedef COMPILER_INLINE_PACK struct _PriorityVector
 {
   BridgeId root_bridge_id;
@@ -381,13 +398,13 @@
   PortId   designated_port_id;
   PortId   bridge_port_id;
 } __attribute__((packed)) PriorityVector;
-#ifdef __ICCARM__
-#pragma pack()
-#endif
-
-#ifdef __ICCARM__
-#pragma pack(1)
-#endif
+#if defined(__ICCARM__) || defined(WINCE_BUILD)
+#pragma pack()
+#endif
+
+#if defined(__ICCARM__) || defined(WINCE_BUILD)
+#pragma pack(1)
+#endif
 /* First 4 components of priority vector */
 typedef COMPILER_INLINE_PACK struct _PriorityVector4
 {
@@ -396,9 +413,9 @@
   BridgeId designated_bridge_id;
   PortId   designated_port_id;
 } __attribute__((packed)) PriorityVector4;
-#ifdef __ICCARM__
-#pragma pack()
-#endif
+#if defined(__ICCARM__) || defined(WINCE_BUILD)
+#pragma pack()
+#endif
 
 typedef struct _Times
 {
@@ -467,9 +484,9 @@
 
 #define STP_PROTOCOL_ID 0
 
-#ifdef __ICCARM__
-#pragma pack(1)
-#endif
+#if defined(__ICCARM__) || defined(WINCE_BUILD)
+#pragma pack(1)
+#endif
 typedef COMPILER_INLINE_PACK struct _RawBPDU
 {
   uint16 protocol_id;
@@ -506,9 +523,9 @@
   uchar RST_END[0];
 #endif
 } __attribute__((packed)) RawBPDU;
-#ifdef __ICCARM__
-#pragma pack()
-#endif
+#if defined(__ICCARM__) || defined(WINCE_BUILD)
+#pragma pack()
+#endif
 
 
 #ifndef __GNU_C
@@ -1156,6 +1173,7 @@
     /* Becoming nonzero from zero */
     BRIDGE->tc_count++;
     BRIDGE->time_since_tc = 0;
+    STP_OUT_topologychanged(1);
   }
 
   BRIDGE->tcWhile_count+= change;
@@ -1382,7 +1400,7 @@
 
   set_bpdu_times(&b, &designatedTimes);
 
-  DEBUG("Sending Config BPDU\n");
+  STP_DEBUG_PRINT("Sending Config BPDU\n");
 #ifndef __GNUC__
   STP_OUT_tx_bpdu(PORT->user_ref, &b, CONFIG_END_SIZE_BYTES);
 #else
@@ -1424,7 +1442,7 @@
 
   b.version1_len = 0;
 
-  DEBUG("Sending RST BPDU\n");
+  STP_DEBUG_PRINT("Sending RST BPDU\n");
 #ifndef __GNUC__
   STP_OUT_tx_bpdu(PORT->user_ref, &b, RST_END_SIZE_BYTES);
 #else
@@ -1441,7 +1459,7 @@
   b.version = 0;
   b.type = BPDUTypeTCN;
 
-  DEBUG("Sending TCN BPDU\n");
+  STP_DEBUG_PRINT("Sending TCN BPDU\n");
 #ifndef __GNUC__
   STP_OUT_tx_bpdu(PORT->user_ref, &b, TCN_END_SIZE_BYTES);
 #else
@@ -1594,9 +1612,9 @@
                  }
                  break;
                default:
-                 ERROR("Unknown value for infoIs: %d\n", infoIs);
+                 STP_ERROR_PRINT("Unknown value for infoIs: %d\n", infoIs);
                }
-                 DEBUG("Selected Role Set to: %d\n", selectedRole);
+                 STP_DEBUG_PRINT("Selected Role Set to: %d\n", selectedRole);
                );
 }
 
@@ -2642,7 +2660,7 @@
     return; // No action - else we might fail the next test
 
   if (rcvdBpdu) {
-    ABORT("Port hasn't processed old BPDU\n");
+    STP_ABORT("Port hasn't processed old BPDU\n");
     return;
   }
 
@@ -2652,7 +2670,7 @@
   if (p->protocol_id != STP_PROTOCOL_ID)
     return;
 
-  DEBUG("Received BPDU of type %d\n", p->type);
+  STP_DEBUG_PRINT("Received BPDU of type %d\n", p->type);
 
   if (// 9.3.4 a)
       (p->type == BPDUTypeConfig &&
@@ -2673,7 +2691,7 @@
     /* BPDU has been validated */
   }
   else {
-    DEBUG("BPDU validation failed\n");
+    STP_DEBUG_PRINT("BPDU validation failed\n");
     return;
   }
 
@@ -2723,7 +2741,7 @@
 static int check_times(BRIDGE_ARGS_PROTO, int max_age, int fwd_delay)
 {
   if (2*(fwd_delay - 1) < max_age) {
-    ERROR("Configured BridgeTimes doesn't meet "
+    STP_ERROR_PRINT("Configured BridgeTimes doesn't meet "
           "2 * (Bridge Foward Delay - 1) >= Bridge Max Age\n");
     return -1;
   }
@@ -2731,7 +2749,7 @@
   // This condition never fails, with hello_time == 2 && max_age >= 6.
   // So no need to check.
   //if (max_age < 2*(BridgeHelloTime + 1)) {
-  //  ERROR("Doesn't meet Bridge Max Age >= 2 * (Bridge Hello Time + 1) ");
+  //  STP_ERROR_PRINT("Doesn't meet Bridge Max Age >= 2 * (Bridge Hello Time + 1) ");
   //  return -1;
   //}
 
@@ -2750,7 +2768,7 @@
 
   if (cfg->set_bridge_protocol_version) {
     if (cfg->bridge_protocol_version != 0 && cfg->bridge_protocol_version != 2) {
-      ERROR("Protocol version must be 0 or 2\n");
+      STP_ERROR_PRINT("Protocol version must be 0 or 2\n");
       r = -1;
     }
   }
@@ -2760,7 +2778,7 @@
   if (cfg->set_bridge_priority) {
     // 17.14 - Table 17-2
     if (cfg->bridge_priority & ~0xf000) {
-      ERROR("Bridge Priority restricted to 0-61440 in steps of 4096\n");
+      STP_ERROR_PRINT("Bridge Priority restricted to 0-61440 in steps of 4096\n");
       r = -1;
     }
   }
@@ -2771,7 +2789,7 @@
   if (cfg->set_bridge_hello_time) {
     // 17.14 - Table 17-1
     if (cfg->bridge_hello_time != BridgeHelloTime) {
-      ERROR("Hello Time cannot be changed from 2s in RSTP\n");
+      STP_ERROR_PRINT("Hello Time cannot be changed from 2s in RSTP\n");
       r = -1;
     }
     new_times.hello_time = cfg->bridge_hello_time;
@@ -2781,7 +2799,7 @@
   if (cfg->set_bridge_max_age) {
     // 17.14 - Table 17-1
     if (cfg->bridge_max_age < 6 || cfg->bridge_max_age > 40) {
-      ERROR("Bridge Max Age must be between 6 and 40\n");
+      STP_ERROR_PRINT("Bridge Max Age must be between 6 and 40\n");
       r = -1;
     }
     new_times.max_age = cfg->bridge_max_age;
@@ -2791,7 +2809,7 @@
   if (cfg->set_bridge_forward_delay) {
     // 17.14 - Table 17-1
     if (cfg->bridge_forward_delay < 4 || cfg->bridge_forward_delay > 30) {
-      ERROR("Bridge Forward Delay must be between 4 and 30\n");
+      STP_ERROR_PRINT("Bridge Forward Delay must be between 4 and 30\n");
       r = -1;
     }
     new_times.forward_delay = cfg->bridge_forward_delay;
@@ -2804,7 +2822,7 @@
   if (cfg->set_bridge_tx_hold_count) {
     // 17.14 - Table 17-1
     if (cfg->bridge_tx_hold_count < 1 || cfg->bridge_tx_hold_count > 10) {
-      ERROR("Transmit Hold Count must be between 1 and 10\n");
+      STP_ERROR_PRINT("Transmit Hold Count must be between 1 and 10\n");
       r = -1;
     }
   }
@@ -2906,7 +2924,7 @@
   if (cfg->set_port_priority) {
     // 17.14 - Table 17-2
     if (cfg->port_priority & ~0xf0) {
-      ERROR("Port Priority restricted to 0-240 in steps of 16\n");
+      STP_ERROR_PRINT("Port Priority restricted to 0-240 in steps of 16\n");
       r = -1;
     }
   }
@@ -2914,28 +2932,28 @@
   if (cfg->set_port_pathcost) {
     // 17.14 - Note 3 and Table 17-3
     if (cfg->port_pathcost > 200000000) {
-      ERROR("Port path cost restricted to 1-200,000,000 or 0 for auto\n");
+      STP_ERROR_PRINT("Port path cost restricted to 1-200,000,000 or 0 for auto\n");
       r = -1;
     }
   }
 
   if (cfg->set_port_admin_edge) {
     if (cfg->port_admin_edge != 0 && cfg->port_admin_edge != 1) {
-      ERROR("Admin Edge must be 0 or 1\n");
+      STP_ERROR_PRINT("Admin Edge must be 0 or 1\n");
       r = -1;
     }
   }
 
   if (cfg->set_port_auto_edge) {
     if (cfg->port_auto_edge != 0 && cfg->port_auto_edge != 1) {
-      ERROR("Auto Edge must be 0 or 1\n");
+      STP_ERROR_PRINT("Auto Edge must be 0 or 1\n");
       r = -1;
     }
   }
 
   if (cfg->set_port_admin_p2p) {
     if (cfg->port_admin_p2p < 0 || cfg->port_admin_p2p > 2) {
-      ERROR("Admin P2P must be "
+      STP_ERROR_PRINT("Admin P2P must be "
             "0 (force false), 1 (force true), or 2 (auto)\n");
       r = -1;
     }
@@ -3126,7 +3144,7 @@
   Bridge *BRIDGE = PORT->bridge;
 
   if (!BRIDGE->stp_on) {
-    ERROR("Bridge is down\n");
+    STP_ERROR_PRINT("Bridge is down\n");
     return -1;
   }
 
@@ -3221,7 +3239,7 @@
   Bridge *b = STP_OUT_mem_zalloc(sizeof(Bridge));
 
   if (!b) {
-    ERROR("Couldn't allocate memory for bridge\n");
+    STP_ERROR_PRINT_NO_REFS("Couldn't allocate memory for bridge\n");
     return NULL;
   }
 
@@ -3268,14 +3286,14 @@
   Port *PORT;
 
   if (port_number == 0 || (port_number & ~0x0fff)) {
-    ERROR("Port id should be in the range 1 - 1023\n");
+    STP_ERROR_PRINT_NO_REFS("Port id should be in the range 1 - 1023\n");
     return NULL;
   }
 
   p = STP_OUT_mem_zalloc(sizeof(Port));
 
   if (!p) {
-    ERROR("Couldn't allocate memory for port\n");
+    STP_ERROR_PRINT_NO_REFS("Couldn't allocate memory for port\n");
     return NULL;
   }
 
@@ -3312,7 +3330,7 @@
 void STP_IN_port_delete(Port *PORT)
 {
   Bridge *BRIDGE = PORT->bridge;
-  Port **prev; 
+  Port **prev;
 
   /* Disable */
   if (portEnabled) {
@@ -3326,7 +3344,7 @@
     prev = &(*prev)->port_next;
 
   if (*prev == NULL)
-    ABORT("port not in its bridge's list\n");
+    STP_ABORT("port not in its bridge's list\n");
 
   /* Remove from list */
   *prev = PORT->port_next;
