Ejemplo n.º 1
0
	def _initiate_schedule(self, node):
		cells = self.frames['mainstream'].get_cells_of(node)
		dag_neighbors = []
		parent = self.dodag.get_parent(node)
		if parent:
			dag_neighbors += [parent]
		#children = self.dodag.get_children(node)
		#if children:
		#	dag_neighbors += children
		q = BlockQueue()
		for neighbor in dag_neighbors:
			flags = 0
			for cell in cells:
				if cell.tna == neighbor:
					if cell.option & 1 == 1:
						flags |= 1
					elif cell.option & 2 == 2:
						flags |= 2
			if flags & 1 == 0:
				so,co = self.schedule(node, neighbor, self.frames["mainstream"])
				if so is not None and co is not None:
					q.push(self.post_link(so, co, self.frames["mainstream"], node, neighbor))
					self.reserved_cells.append(Cell(node,so,co,self.frames["mainstream"].get_alias_id(node),0,1,neighbor))
					self.reserved_cells.append(Cell(neighbor,so,co,self.frames["mainstream"].get_alias_id(neighbor),0,2,node))
				else:
					logg.critical("INSUFFICIENT SLOTS: node " + str(node) + " cannot use more cells")
			if flags & 2 == 0:
				so,co = self.schedule(neighbor, node, self.frames["mainstream"])
				if so is not None and co is not None:
					q.push(self.post_link(so, co, self.frames["mainstream"], neighbor, node))
					self.reserved_cells.append(Cell(node,so,co,self.frames["mainstream"].get_alias_id(node),0,2,neighbor))
					self.reserved_cells.append(Cell(neighbor,so,co,self.frames["mainstream"].get_alias_id(neighbor),0,1,node))
				else:
					logg.critical("INSUFFICIENT SLOTS: node " + str(neighbor) + " cannot use more cells")
		return q
Ejemplo n.º 2
0
	def Schedule_Link(self, tx, rx, slotframe,q):
		uso, uco = self.schedule(tx, rx, slotframe)
		if uso is not None and uco is not None:
			q.push(self.set_remote_link(uso, uco, slotframe, tx, rx))
		else:
			logg.critical("INSUFFICIENT " + slotframe.name + " SLOTS: new node " + str(rx) + " cannot receive from " + str(tx))
		return q
Ejemplo n.º 3
0
	def deschedule(self, tx, rx, slotframe):
		"""
		Schedules a link at a given slotframe.

		Starts from slot 1 and channel 0. All the channels of the slot are scanned. If the intended link does not conflict
		with any simultaneous transmission at that slot and does not interfere with any other pair of nodes, the link is
		scheduled at that channel and slot. If no such channel can be found, the next slot is scanned.

		Note that the slots and channels of both Broadcast-Frame and Unicast-Frame slotframes are considered to avoid conflicts
		and interferences.

		:note: all 16 channels are assumed available

		:param tx: the transmitting node
		:type tx: NodeID
		:param rx: the receiving node or None if broadcast link to be scheduled
		:type rx: NodeID or None
		:param slotframe: the slotframe the link should be scheduled to
		:type slotframe: Slotframe
		:return: (slotoffset, channeloffset)
		:rtype: (int,int) tuple of (None,None) tuple if cell not found
		"""

		so = None
		co = None
		cells = slotframe.get_cells_similar_to(owner=tx,tna=rx,link_option=1)
		if len(cells) == 1:
			so = cells[0].slot
			co = cells[0].channel
			cells = slotframe.get_cells_similar_to(owner=rx,tna=tx,link_option=2)
			if len(cells) == 1 and so == cells[0].slot and co == cells[0].channel:
				return so,co
			else:
				logg.critical("plexiflex in panic. did not find expected cell")
		return None, None
Ejemplo n.º 4
0
 def Schedule_Link(self, tx, rx, slotframe, q):
     uso, uco = self.schedule(tx, rx, slotframe)
     if uso is not None and uco is not None:
         q.push(self.post_link(uso, uco, slotframe, tx, rx))
     else:
         logg.critical("INSUFFICIENT " + slotframe.name +
                       " SLOTS: new node " + str(rx) +
                       " cannot receive from " + str(tx))
     return q
Ejemplo n.º 5
0
 def _initiate_schedule(self, node):
     cells = self.frames['mainstream'].get_cells_of(node)
     dag_neighbors = []
     parent = self.dodag.get_parent(node)
     if parent:
         dag_neighbors += [parent]
     #children = self.dodag.get_children(node)
     #if children:
     #	dag_neighbors += children
     q = BlockQueue()
     for neighbor in dag_neighbors:
         flags = 0
         for cell in cells:
             if cell.tna == neighbor:
                 if cell.option & 1 == 1:
                     flags |= 1
                 elif cell.option & 2 == 2:
                     flags |= 2
         if flags & 1 == 0:
             so, co = self.schedule(node, neighbor,
                                    self.frames["mainstream"])
             if so is not None and co is not None:
                 q.push(
                     self.post_link(so, co, self.frames["mainstream"], node,
                                    neighbor))
                 self.reserved_cells.append(
                     Cell(node, so, co,
                          self.frames["mainstream"].get_alias_id(node), 0,
                          1, neighbor))
                 self.reserved_cells.append(
                     Cell(neighbor, so, co,
                          self.frames["mainstream"].get_alias_id(neighbor),
                          0, 2, node))
             else:
                 logg.critical("INSUFFICIENT SLOTS: node " + str(node) +
                               " cannot use more cells")
         if flags & 2 == 0:
             so, co = self.schedule(neighbor, node,
                                    self.frames["mainstream"])
             if so is not None and co is not None:
                 q.push(
                     self.post_link(so, co, self.frames["mainstream"],
                                    neighbor, node))
                 self.reserved_cells.append(
                     Cell(node, so, co,
                          self.frames["mainstream"].get_alias_id(node), 0,
                          2, neighbor))
                 self.reserved_cells.append(
                     Cell(neighbor, so, co,
                          self.frames["mainstream"].get_alias_id(neighbor),
                          0, 1, node))
             else:
                 logg.critical("INSUFFICIENT SLOTS: node " + str(neighbor) +
                               " cannot use more cells")
     return q
Ejemplo n.º 6
0
    def deschedule(self, tx, rx, slotframe):
        """
		Schedules a link at a given slotframe.

		Starts from slot 1 and channel 0. All the channels of the slot are scanned. If the intended link does not conflict
		with any simultaneous transmission at that slot and does not interfere with any other pair of nodes, the link is
		scheduled at that channel and slot. If no such channel can be found, the next slot is scanned.

		Note that the slots and channels of both Broadcast-Frame and Unicast-Frame slotframes are considered to avoid conflicts
		and interferences.

		:note: all 16 channels are assumed available

		:param tx: the transmitting node
		:type tx: NodeID
		:param rx: the receiving node or None if broadcast link to be scheduled
		:type rx: NodeID or None
		:param slotframe: the slotframe the link should be scheduled to
		:type slotframe: Slotframe
		:return: (slotoffset, channeloffset)
		:rtype: (int,int) tuple of (None,None) tuple if cell not found
		"""

        so = None
        co = None
        cells = slotframe.get_cells_similar_to(owner=tx, tna=rx, link_option=1)
        if len(cells) == 1:
            so = cells[0].slot
            co = cells[0].channel
            cells = slotframe.get_cells_similar_to(owner=rx,
                                                   tna=tx,
                                                   link_option=2)
            if len(cells
                   ) == 1 and so == cells[0].slot and co == cells[0].channel:
                return so, co
            else:
                logg.critical("plexiflex in panic. did not find expected cell")
        return None, None
Ejemplo n.º 7
0
	def connected(self, child, parent, old_parent=None):
		"""
		Configure newly connected node to communicate with neighbors. Configure both child and its neighbors as follows:

		- a broadcast frame of 25 slots and a unicast frame of 21 slots
		- a transmitting broadcast cell at child for the child's (Tx) broadcasting to its neighbors (Rx)
		- the receiving broadcast cells at the neighbors for child's broadcast
		- receiving only broadcast cells at child for neighbors' broadcasts
		- one transmit unicast cell at child for every unicast child->neighbor link
		- one receive unicast cell at a neighbor for every unicast child->neighbor link
		- one transmit unicast cell at neighbor for every unicast neighbor->child link
		- one receive unicast cell at child for every unicast neighbor->child link
		- an observer of the PRR and RSSI statistics

		:param child: the newly connected node
		:type child: NodeID
		:param parent: the current parent of child at the DoDAG
		:type parent: NodeID
		:param old_parent: the previous parent of child at the DoDAG (in case of rewiring)
		:type old_parent: NodeID or None -if not rewiring-
		:return: list of BlockQueues that handle the all concurrent transactions with the node and its neighbors
		"""

		# Make a list of BlockQueues that should be transmitted simultaneously
		commands = []

		# Define a BlockQueue for broadcast cells. Make sure to block() before cells are added to this BlockQueue
		bcq = self.set_remote_frames(child, self.frames["Broadcast-Frame"])

		# Scan through all broadcast cells to detect those that the child (new node) should listen to.
		# As soon as one is found, create a Tx cell and append it to the broadcast frame
		# Be careful. Avoid scanning through the cells you just create
		for c in self.frames["Broadcast-Frame"].cell_container:
			skip = False
			for new_command in bcq:
				if new_command.uri == terms.uri['6TP_CL'] and c.slot == new_command.payload['so'] and c.channel == new_command.payload['co'] and c.option == new_command.payload['lo'] and c.owner == new_command.to and c.type == new_command.payload['lt']:
					skip = True
			if skip:
				continue
			if c.tx == parent or c.tx in self.dodag.get_children(child):
				# Note that set_remote_link modifies the cell_container you are also reading in this loop
				bcq.push(self.set_remote_link(c.slot, c.channel, self.frames["Broadcast-Frame"], c.tx, None, child))

		# Schedule a broadcast cell for the child, if there is space in the Broadcast-Frame
		bso, bco = self.schedule(child, None, self.frames["Broadcast-Frame"])
		if bso is not None and bco is not None:
			bcq.push(self.set_remote_link(bso, bco, self.frames["Broadcast-Frame"], child, None))
		else:
			logg.critical("INSUFFICIENT BROADCAST SLOTS: new node " + str(child) + " cannot broadcast")
		bcq.block()

		commands.append(bcq)

		# Define another BlockQueue for unicast cells. Make sure to block() before cells are added to this BlockQueue
		ucq = self.set_remote_frames(child, self.frames["Unicast-Frame"])

		# Allocate one unicast cell per links with every neighbor of child
		for neighbor in [parent]+self.dodag.get_children(child):
			# schedule the neighbor->child link
			# uso, uco = self.schedule(neighbor, child, self.frames["Unicast-Frame"])
			# if uso is not None and uco is not None:
			# 	ucq.push(self.set_remote_link(uso, uco, self.frames["Unicast-Frame"], neighbor, child))
			# else:
			# 	logg.critical("INSUFFICIENT UNICAST SLOTS: new node " + str(child) + " cannot receive from " + str(neighbor))
			ucq = self.Schedule_Link(neighbor, child, self.frames["Unicast-Frame"], ucq)

			# schedule the child->neighbor link
			# uso, uco = self.schedule(child, neighbor, self.frames["Unicast-Frame"])
			# if uso is not None and uco is not None:
			# 	ucq.push(self.set_remote_link(uso, uco, self.frames["Unicast-Frame"], child, neighbor))
			# else:
			# 	logg.critical("INSUFFICIENT UNICAST SLOTS: new node " + str(child) + " cannot unicast to " + str(neighbor))
			ucq = self.Schedule_Link(child, neighbor, self.frames["Unicast-Frame"], ucq)
		ucq.block()
		commands.append(ucq)

		# Build and send a BlockQueue for a statistics observer
		commands.append(self.set_remote_statistics(child, {"mt":"[\"PRR\",\"RSSI\",\"ETX\"]"}))

		return commands
Ejemplo n.º 8
0
    def connected(self, child, parent, old_parent=None):
        """
		Configure newly connected node to communicate with neighbors. Configure both child and its neighbors as follows:

		- a broadcast frame of 25 slots and a unicast frame of 21 slots
		- a transmitting broadcast cell at child for the child's (Tx) broadcasting to its neighbors (Rx)
		- the receiving broadcast cells at the neighbors for child's broadcast
		- receiving only broadcast cells at child for neighbors' broadcasts
		- one transmit unicast cell at child for every unicast child->neighbor link
		- one receive unicast cell at a neighbor for every unicast child->neighbor link
		- one transmit unicast cell at neighbor for every unicast neighbor->child link
		- one receive unicast cell at child for every unicast neighbor->child link
		- an observer of the PRR and RSSI statistics

		:param child: the newly connected node
		:type child: NodeID
		:param parent: the current parent of child at the DoDAG
		:type parent: NodeID
		:param old_parent: the previous parent of child at the DoDAG (in case of rewiring)
		:type old_parent: NodeID or None -if not rewiring-
		:return: list of BlockQueues that handle the all concurrent transactions with the node and its neighbors
		"""

        # Make a list of BlockQueues that should be transmitted simultaneously
        commands = []

        # Define a BlockQueue for broadcast cells. Make sure to block() before cells are added to this BlockQueue
        bcq = self.set_remote_frames(child, self.frames["Broadcast-Frame"])

        # Scan through all broadcast cells to detect those that the child (new node) should listen to.
        # As soon as one is found, create a Tx cell and append it to the broadcast frame
        # Be careful. Avoid scanning through the cells you just create
        for c in self.frames["Broadcast-Frame"].cell_container:
            skip = False
            for new_command in bcq:
                if new_command.uri == terms.uri[
                        '6TP_CL'] and c.slot == new_command.payload[
                            'so'] and c.channel == new_command.payload[
                                'co'] and c.option == new_command.payload[
                                    'lo'] and c.owner == new_command.to and c.type == new_command.payload[
                                        'lt']:
                    skip = True
            if skip:
                continue
            if c.tx == parent or c.tx in self.dodag.get_children(child):
                # Note that post_links modifies the cell_container you are also reading in this loop
                bcq.push(
                    self.post_link(c.slot, c.channel,
                                   self.frames["Broadcast-Frame"], c.tx, None,
                                   child))

        # Schedule a broadcast cell for the child, if there is space in the Broadcast-Frame
        bso, bco = self.schedule(child, None, self.frames["Broadcast-Frame"])
        if bso is not None and bco is not None:
            bcq.push(
                self.post_link(bso, bco, self.frames["Broadcast-Frame"], child,
                               None))
        else:
            logg.critical("INSUFFICIENT BROADCAST SLOTS: new node " +
                          str(child) + " cannot broadcast")
        bcq.block()

        commands.append(bcq)

        # Define another BlockQueue for unicast cells. Make sure to block() before cells are added to this BlockQueue
        ucq = self.set_remote_frames(child, self.frames["Unicast-Frame"])

        # Allocate one unicast cell per links with every neighbor of child
        for neighbor in [parent] + self.dodag.get_children(child):
            # schedule the neighbor->child link
            # uso, uco = self.schedule(neighbor, child, self.frames["Unicast-Frame"])
            # if uso is not None and uco is not None:
            # 	ucq.push(self.post_links(uso, uco, self.frames["Unicast-Frame"], neighbor, child))
            # else:
            # 	logg.critical("INSUFFICIENT UNICAST SLOTS: new node " + str(child) + " cannot receive from " + str(neighbor))
            ucq = self.Schedule_Link(neighbor, child,
                                     self.frames["Unicast-Frame"], ucq)

            # schedule the child->neighbor link
            # uso, uco = self.schedule(child, neighbor, self.frames["Unicast-Frame"])
            # if uso is not None and uco is not None:
            # 	ucq.push(self.post_links(uso, uco, self.frames["Unicast-Frame"], child, neighbor))
            # else:
            # 	logg.critical("INSUFFICIENT UNICAST SLOTS: new node " + str(child) + " cannot unicast to " + str(neighbor))
            ucq = self.Schedule_Link(child, neighbor,
                                     self.frames["Unicast-Frame"], ucq)
        ucq.block()
        commands.append(ucq)

        # Build and send a BlockQueue for a statistics observer
        commands.append(
            self.set_remote_statistics(child,
                                       {"mt": "[\"PRR\",\"RSSI\",\"ETX\"]"}))

        return commands