Changed bridge structure to hold 1..n members instead of only 1..2
[lcr.git] / port.cpp
index 4afca9c..a05deca 100644 (file)
--- a/port.cpp
+++ b/port.cpp
@@ -1177,20 +1177,21 @@ static void remove_bridge(struct port_bridge *bridge, class Port *port)
        struct port_bridge **temp = &p_bridge_first;
        while (*temp) {
                if (*temp == bridge) {
-                       int remove = 0;
-
-                       /* Remove us from bridge. If bridge is empty, remove it completely. */
-                       if (bridge->sunrise == port) {
-                               bridge->sunrise = NULL;
-                               if (!bridge->sunset)
-                                       remove = 1;
-                       }
-                       if (bridge->sunset == port) {
-                               bridge->sunset = NULL;
-                               if (!bridge->sunrise)
-                                       remove = 1;
+                       struct port_bridge_member **memberp = &bridge->first, *member;
+
+                       /* loop until we are found */
+                       while(*memberp) {
+                               if ((*memberp)->port == port) {
+                                       member = *memberp;
+                                       *memberp = member->next;
+                                       FREE(member, sizeof(struct port_bridge_member));
+                                       memuse--;
+                                       break;
+                               }
+                               memberp = &((*memberp)->next);
                        }
-                       if (remove) {
+                       /* if bridge is empty, remove it */
+                       if (bridge->first == NULL) {
                                PDEBUG(DEBUG_PORT, "Remove bridge %u\n", bridge->bridge_id);
                                *temp = bridge->next;
                                FREE(bridge, sizeof(struct port_bridge));
@@ -1205,6 +1206,8 @@ static void remove_bridge(struct port_bridge *bridge, class Port *port)
 
 void Port::bridge(unsigned int bridge_id)
 {
+       struct port_bridge_member **memberp;
+
        /* Remove bridge, if we leave bridge or if we join a different bridge. */
        if (p_bridge && bridge_id != p_bridge->bridge_id) {
                PDEBUG(DEBUG_PORT, "Remove port %u from bridge %u, because out new bridge is %u\n", p_serial, p_bridge->bridge_id, bridge_id);
@@ -1237,7 +1240,6 @@ void Port::bridge(unsigned int bridge_id)
                p_bridge = (struct port_bridge *) MALLOC(sizeof(struct port_bridge));
                memuse++;
                p_bridge->bridge_id = bridge_id;
-               p_bridge->sunrise = this;
 
                /* attach bridge instance to list */
                while (*temp)
@@ -1246,41 +1248,45 @@ void Port::bridge(unsigned int bridge_id)
                PDEBUG(DEBUG_PORT, "Port %d creating not existing bridge %u.\n", p_serial, p_bridge->bridge_id);
        }
 
-       /* already joined */
-       if (p_bridge->sunrise == this || p_bridge->sunset == this)
-               return;
-
-       /* join bridge */
-       if (!p_bridge->sunrise) {
-               p_bridge->sunrise = this;
-               return;
-       }
-       if (!p_bridge->sunset) {
-               p_bridge->sunset = this;
-               return;
+       /* attach to bridge */
+       memberp = &p_bridge->first;
+       while(*memberp) {
+               if ((*memberp)->port == this) {
+                       /* already joined */
+                       return;
+               }
+               memberp = &((*memberp)->next);
        }
-       
-       PERROR("Bridge ID %u cannot be joined by port %u, because it is already occupied by ports %u and %u.\n", p_bridge->bridge_id, p_serial, p_bridge->sunrise->p_serial, p_bridge->sunset->p_serial);
-       p_bridge = NULL;
+       *memberp = (struct port_bridge_member *) MALLOC(sizeof(struct port_bridge_member));
+       memuse++;
+       (*memberp)->port = this;
+}
+
+class Port *Port::bridge_remote(void)
+{
+       class Port *remote = NULL;
+
+       /* get remote port from bridge */
+       if (!p_bridge || !p_bridge->first || !p_bridge->first->next)
+               return NULL;
+       if (p_bridge->first->port == this)
+               remote = p_bridge->first->next->port;
+       if (p_bridge->first->next->port == this)
+               remote = p_bridge->first->port;
+
+       return remote;
 }
 
 /* send data to remote Port */
 int Port::bridge_tx(unsigned char *data, int len)
 {
-       class Port *to_port = NULL;
+       class Port *remote = bridge_remote();
 
-       /* get remote port from bridge */
-       if (!p_bridge)
-               return -EINVAL;
-       if (p_bridge->sunrise == this)
-               to_port = p_bridge->sunset;
-       if (p_bridge->sunset == this)
-               to_port = p_bridge->sunrise;
-       if (!to_port)
+       if (!remote)
                return -EINVAL;
 
-//     printf("Traffic: %u -> %u (bridge %u)\n", p_serial, to_port->p_serial, p_bridge->bridge_id);
-       return to_port->bridge_rx(data, len);
+//     printf("Traffic: %u -> %u (bridge %u)\n", p_serial, remote->p_serial, p_bridge->bridge_id);
+       return remote->bridge_rx(data, len);
 }
 
 /* receive data from remote Port (dummy, needs to be inherited) */