Example #1
0
    def start_sensing(self, samp_num):
        # broadcast the start command to all the nodes to start
        # the first round of data collection
        # Only head can broadcast this command
        # The node with id = 0 need to report the data after this command
        print 'start_round_robin'

        if self.node_type != CLUSTER_HEAD:
            print 'Only cluster head can start the data collect'
            return 1
        
        if self.state != HEAD_IDLE and self.state != ROUND_COLLECTED:
            print 'The sensing can only be initiated when Head is idle state'
            return 1
            
        pkt_size = struct.pack('!H', 26) # (2) include the pktno(4) 
        fromaddr = struct.pack('!I', HEAD_ADDR) #(4)
        toaddr = struct.pack('!I', BCST_ADDR) #(4)       
        pkt_type = struct.pack('!B', CTRL_TYPE) #(1)
        ctrl_cmd = struct.pack('!B', START_SENSE)# (1)
        current_time = self.tb.source.u.get_time_now().get_real_secs()
        print '***************************************This round of collection initated at time ', current_time
        start_time = current_time   #0.09s is the switching time of half-duplex
        print 'start_time = %.7f' %start_time
        self.current_start_time = start_time
        start_time = struct.pack('!d', start_time) # (8)
        samp_num = struct.pack('!H', samp_num) # (2)
        
        payload = pkt_size + fromaddr + toaddr + pkt_type + ctrl_cmd + start_time + samp_num        
      
        self.output.put(payload)
        print "start_sense =", pkt_utils.string_to_hex_list(payload)
        
        self.state = SENSE_START
    def send_pkt(self, seqNr, addressInfo, payload='', eof=False):
        """
        Send the payload.

        @param seqNr: sequence number of packet
        @type seqNr: byte
        @param addressInfo: address information for packet
        @type addressInfo: string
        @param payload: data to send
        @type payload: string
        """

        if eof:
            msg = gr.message(1) # tell self.pkt_input we're not sending any more packets
        else:
            FCF = make_FCF()

            pkt = make_ieee802_15_4_packet(FCF,
                                           seqNr,
                                           addressInfo,
                                           payload,
                                           self.pad_for_usrp)
            print "pkt =", packet_utils.string_to_hex_list(pkt), len(pkt)
            msg = gr.message_from_string(pkt)
        self.pkt_input.msgq().insert_tail(msg)
Example #3
0
 def round_data_collect(self, tran_id, node_id): #usingthe start time as tran_id
     # broadcast the data collect command to all the node, but only the specified node report
     if self.node_type != CLUSTER_HEAD:
         print 'Only cluster head can start the data collect'
         return 1
     
     if (self.state != SENSE_START and self.state != ROUND_COLLECTING):
         print 'Round robin data collection can only be performed when SENSE_START or  ROUND_COLLECTING state'
         return 1
         
     pkt_size = struct.pack('!H', 26) # (2) include the pktno(4) 
     fromaddr = struct.pack('!I', HEAD_ADDR) # (4)
     toaddr = struct.pack('!I', BCST_ADDR) # (4)
     pkt_type = struct.pack('!B', CTRL_TYPE) # (1)
     ctrl_cmd = struct.pack('!B', COLLECT_DATA)  # (1)
     node_id = struct.pack('!H', node_id) # (2)
     tid = struct.pack('!d', tran_id) # (8)
        
     payload = pkt_size + fromaddr + toaddr + pkt_type + ctrl_cmd + node_id + tid
         
     print 'round robin collect from node ', node_id
     print "round_collect =", pkt_utils.string_to_hex_list(payload)
     self.output.put(payload)
Example #4
0
    def send_pkt(self, seqNr, addressInfo, payload='', eof=False):
        """
        Send the payload.

        @param seqNr: sequence number of packet
        @type seqNr: byte
        @param addressInfo: address information for packet
        @type addressInfo: string
        @param payload: data to send
        @type payload: string
        """

        if eof:
            msg = gr.message(
                1)  # tell self.pkt_input we're not sending any more packets
        else:
            FCF = make_FCF()

            pkt = make_ieee802_15_4_packet(FCF, seqNr, addressInfo, payload,
                                           self.pad_for_usrp)
            print "pkt =", packet_utils.string_to_hex_list(pkt), len(pkt)
            msg = gr.message_from_string(pkt)
        self.pkt_input.msgq().insert_tail(msg)
Example #5
0
    def process_payload(self, payload, options):       
        #print 'process_pay_load'
        
        length = len(payload)
        #test code
        #if length == 12:
        #   time.sleep(0.008)
        #   self.round_data_collect(0, 1)
        
        if length <= 17:
            print 'useless payload'
            return 1              
        
        (pktno, pktsize, fromaddr, toaddr, pkttype) = struct.unpack('!IHIIB', payload[0:15])
 
        if length != pktsize:
            print 'invalid payload'
            return 1 
        ####State Machine For the Cluster Head    
        if self.node_type == "head":
            if pkttype == DATA_TYPE:
                rt = self.tb.source.u.get_time_now().get_real_secs()
                print 'recieve the data at time %.7f' %rt
                
                (node_id,) = struct.unpack('!H', payload[15:17])
                if self.state == SENSE_START:
                    if node_id == 0 and self.current_rep_id == -1:  #Got data from the 1st node
                        #print "incoming_payload =", pkt_utils.string_to_hex_list(payload)
                        
                        rt = self.defragment(payload, node_id)               
                        if rt == 0: #Need next packet from the same node
                            return 0
                        elif rt == 1: #Completed collection of all the framgmented packets
                            self.state = ROUND_COLLECTING
                        elif rt > 1 or rt < 0:  #Errors
                            # need to add code to reset all the nodes
                            self.state = HEAD_IDLE
                            return 1
                    else:
                        print 'incorrect incoming data from node ', node_id
                        # Could broadcast the reset command to reset all the nodes
                        self.state = HEAD_IDLE
                        return 1
                elif self.state == ROUND_COLLECTING:
                    if node_id == self.current_rep_id: 
                        #print "incoming_payload =", pkt_utils.string_to_hex_list(payload)
                        
                        rt = self.defragment(payload, node_id)
                        if rt == 0: #Need next packet from the same node
                            return 0
                        elif rt > 1 or rt < 0: 
                            #Need to add code for reset the nodes
                            self.state = HEAD_IDLE
                            return 1                        
                        #Completed collection of all the fragemented packets 
                        if self.current_rep_id >= self.net_size - 1:
                            print "last node has reported data"
                            finish_time = self.tb.sensor.u.get_time_now().get_real_secs()
                            print '***************************************This round of collection started at time %.7f' %(self.current_start_time - 0.09)
                            print '==============================This round collection finished at time %.7f'  %finish_time                            
                            self.state = ROUND_COLLECTED
                            self.current_rep_id = -1
                            self.current_loop += 1
                            if self.current_loop < self.loop_number:
                                print 'initiate the next round of sensing'
                                #time.sleep(0.01)
                                self.start_sensing(options.samp_num)
                                self.state = SENSE_START
                                return 0
                            else:
                                self.current_loop = 0
                                print 'Complete all rounds of sesning'
                            
                                if self.process_collected_data() == 1:
                                    print 'All round of sensing data are processed'                                   
                                    self.state = HEAD_IDLE
                                else:
                                    print 'Data error'
                    else:
                        print 'incorrect incoming data from node ', node_id
                        self.state = HEAD_IDLE
                        return 1
                else:
                     print 'Should not receive data in the current state'
                     self.state = HEAD_IDLE
                     return 1
                
                # If reach here, the state should be ROUND_COLLECTING
                if self.state == ROUND_COLLECTING:                              
                    (tran_id,) = struct.unpack('!d', payload[17:25])  # use start time as transaction ID 
                    # Collect the data from the next node
                    t = self.tb.sensor.u.get_time_now().get_real_secs()
                    print '------------------------------------------collect next node at time ',  t
                    self.current_rep_id = node_id + 1  
                    if self.current_rep_id < self.net_size:
                        time.sleep(0.009) #Maybe here the delay can be ignored as the last node don't need to receive it.                    
                        self.round_data_collect(tran_id, self.current_rep_id)
                    else: # should not reach here
                        print 'error in report node id'
                        return 1                        
        ####State machine for the CLuster Node:                   
        elif self.node_type == "node":
            rt = self.tb.sensors[0].u.get_time_now().get_real_secs()
            print 'recieve the commnad at time %.7f' %rt
            #print "incoming_command =", pkt_utils.string_to_hex_list(payload)        
            if pkttype == CTRL_TYPE:                
                (ctrl_cmd,) = struct.unpack('!B', payload[15:16])
                
                print 'pkttype == CTRL_TYPE'                               
                if self.state == NODE_IDLE:
                    print '-->NODE_IDLE'
                    if ctrl_cmd == START_SENSE:  # start sensing received
                        print 'START_SENSE received'
                        self.state = SENSING
                        print '----->SENSING'                        
                        (start_time, samp_num) = struct.unpack('!dH', payload[16:26])
                        self.current_start_time = start_time
                        print "self.current_start_time = ", pkt_utils.string_to_hex_list(payload[16:24])
                        self.current_samp_num =  samp_num
                        print 'samp_num = ', samp_num
                        print 'start_time = %.7f' %(start_time + 0.7)
                        # start the data collection as specified time
                        #sensor_time = self.sensor.u.get_time_now().get_real_secs()
                        #print 'sensor_time = %.7f' %sensor_time
                        
                        #if start_time + 0.015 - sensor_time > 0:
                        for i in range(len(self.sensors)):
                            self.sensors[i].u.set_start_time(uhd.time_spec_t(start_time+0.70))  #started later 0.070s
                        
                        # Start data collecting  
                        if (STREAM_OR_FINITE == 1): #finite acqusition
                            samp_num = int(10*options.sx_samprate)
                            current_t = self.sensor.u.get_time_now().get_real_secs()
                            print 'current time = %.7f' %current_t
                            self.samps = self.sensor.u.finite_acquisition(samp_num)
                            if len(self.samps) == 0:
                                print 'no samps captured'
                                self.state = NODE_IDLE
                                return 0                            
                        elif (STREAM_OR_FINITE == 0): #streaming data collection
                            #start streaming here
                            for i in range(len(self.sensors)):
                                self.sensors[i].u.start()
                            #start the timer
                            self.sense_timer = threading.Timer(STREAM_TIME, self.stop_sensing)
                            self.sense_timer.start()
                            
                            self.state = SENSING
                            return 0  # the data report will be done in timer expiring callback
                        

                        
                        #o_samps = np.array(np.real(self.samps[int(0.5*options.sx_samprate):]))
                        #o_samps.astype('float64').tofile(self.fd) 

                        #print 'samps len = ', len(self.samps)
                        
                        #compute the covariance matrix
                        #mat = []
                        #l_v = 64
                        #for i in range(len(self.samps) - l_v + 1):
                        #    v = []
                        #    for j in range(l_v):
                        #        v.append(abs(self.samps[i + j]))
                        #    mat.append(v)
                            
                        #matx = np.array(mat).T
                        #covmat = np.cov(matx)
                        #trace_cov = np.trace(covmat)
                        
                        #print 'trace is ', trace_cov
                        
                        if self.node_id == 0: # for node 0, just report the data to head
                            print 'begin reporting data, data per pkt = ', options.data_pkt
                            #time.sleep(0.01)  #Don't need to delay due to the sensing time plus the sensing delay there
                            #test code
                            #self.send_test_data()
                            #return 0
                            
                            if self.report_data(self.samps, self.node_id, samp_num, options.data_pkt) == 1:
                                print 'error in reporting data'
                                return 1
                            self.state = NODE_IDLE
                            print '------>NODE_IDLE'
                        else:
                            self.state = WAIT_REPORT
                            print '------>WAIT_REPORT'
                    else:
                        print 'Recieved incorrect cmd in NODE_IDLE state'
                        return 1  
                elif self.state == WAIT_REPORT:
                    print '---->WAIT_REPORT'
                    if ctrl_cmd ==  COLLECT_DATA:
                        print 'COLLECT_DATA received'
                        (node_id, ) =  struct.unpack('!H', payload[16:18])
                        if node_id == self.node_id:
                            print 'begin reporting data, data per pkt = ', options.data_pkt
                            #time.sleep(0.004) #Here we need a delay to ensure the cluster head switched to receiving
                            #test code
                            #self.send_test_data()
                            #return 0
                            
                            self.report_data(self.samps, self.node_id, self.current_samp_num, options.data_pkt)
                            self.state = NODE_IDLE
                    else:
                        print 'Received incorrect cmd in WAIT_REPORT state'
                elif self.state == SENSING:  #only reset command accepted, not added yet
                     print 'Only Reset command accepted at this state, not implemented'                
        else:
            print "error node type"
        
        return 0