コード例 #1
0
    def __init__(self, samples_per_symbol, bits_per_symbol, preamble='', access_code='', pad_for_usrp=True):
        """
        packet_mod constructor.
        
        Args:
            samples_per_symbol: number of samples per symbol
            bits_per_symbol: number of bits per symbol
            access_code: AKA sync vector
            pad_for_usrp: If true, packets are padded such that they end up a multiple of 128 samples
            payload_length: number of bytes in a data-stream slice

        """

	print "here1"
	gr.basic_block.__init__(self,name="packet_encoder",in_sig=[numpy.uint8],out_sig=[numpy.uint8])
        #setup parameters
        self._samples_per_symbol = samples_per_symbol
        self._bits_per_symbol = bits_per_symbol
        self._pad_for_usrp = pad_for_usrp
        if not preamble: #get preamble
            preamble = packet_utils.default_preamble
        if not access_code: #get access code
            access_code = packet_utils.default_access_code
        if not packet_utils.is_1_0_string(preamble):
            raise ValueError, "Invalid preamble %r. Must be string of 1's and 0's" % (preamble,)
        if not packet_utils.is_1_0_string(access_code):
            raise ValueError, "Invalid access_code %r. Must be string of 1's and 0's" % (access_code,)

        self._preamble = preamble
        self._access_code = access_code
        self._pad_for_usrp = pad_for_usrp
        #create blocks
        msg_source = blocks.message_source(gr.sizeof_char, DEFAULT_MSGQ_LIMIT)
        self._msgq_out = msg_source.msgq()
コード例 #2
0
def make_packet(payload, samples_per_symbol, bits_per_symbol,
		preamble, access_code,
                pad_for_usrp=True, do_whitening=False, add_crc=False):
	"""
	Build a packet

	Args:
		payload: packet payload, len [0, 4096]
		samples_per_symbol: samples per symbol (needed for padding calculation) (int)
		bits_per_symbol: (needed for padding calculation) (int)
		preamble: (eg: 10101010...)
		access_code: the sync word
		pad_for_usrp:
		do_whitening: ccxxxx whitening version
		add_crc: add CRC16 (2 bytes) checksum
		
	Packet will have access code at the beginning, followed by length (1 byte), payload
	and finally CRC-16.
	"""

	if not packet_utils.is_1_0_string(preamble):
		raise ValueError, "preamble must be a string containing only 0's and 1's (%r)" % (preamble,)

	if not packet_utils.is_1_0_string(access_code):
		raise ValueError, "access_code must be a string containing only 0's and 1's (%r)" % (access_code,)

	(packed_access_code, padded) = packet_utils.conv_1_0_string_to_packed_binary_string(access_code)
	(packed_preamble, ignore) = packet_utils.conv_1_0_string_to_packed_binary_string(preamble)

	# len
	payload_length = len(payload)
	# header (1 byte)
	pkt_hd = make_header(payload_length)
	# data
	pkt_dt = payload
	# final message
	final_message = ''.join((pkt_hd, pkt_dt))

	# CRC ?
	if add_crc:
		crc = crc16(final_message)
		#print "crc: %02x %02x" % (ord(crc[0:1]), ord(crc[1:2]))
		final_message = ''.join((final_message, crc))

	# Whitening ?
	pkt = ''
	if do_whitening:
		pkt = ''.join((packed_preamble, packed_access_code,  whiten(final_message), '\x55'))
	else:
        	pkt = ''.join((packed_preamble, packed_access_code, final_message, '\x55'))

	# Padding ?
	if pad_for_usrp:
        	usrp_packing = packet_utils._npadding_bytes(len(pkt), samples_per_symbol, bits_per_symbol) * '\x55'
        	pkt = pkt + usrp_packing
	
	return pkt
コード例 #3
0
ファイル: cc1111_packet.py プロジェクト: ttiim/gr-cc1111
    def __init__(self,
                 samples_per_symbol,
                 bits_per_symbol,
                 preamble='',
                 access_code='',
                 pad_for_usrp=True,
                 do_whitening=False,
                 add_crc=False):
        """
		packet_mod constructor.
        
		Args:
			samples_per_symbol: number of samples per symbol
			bits_per_symbol: number of bits per symbol
			access_code: AKA sync vector
			pad_for_usrp: If true, packets are padded such that they end up a multiple of 128 samples
			do_whitening: apply CC111x whitening
			add_crc: add CRC16 
		"""

        #setup parameters
        self._samples_per_symbol = samples_per_symbol
        self._bits_per_symbol = bits_per_symbol
        self._pad_for_usrp = pad_for_usrp
        if not preamble:  #get preamble
            preamble = cc1111_packet_utils.default_preamble
        if not access_code:  #get access code
            access_code = cc1111_packet_utils.default_access_code
        if not packet_utils.is_1_0_string(preamble):
            raise ValueError, "Invalid preamble %r. Must be string of 1's and 0's" % (
                preamble, )
        if not packet_utils.is_1_0_string(access_code):
            raise ValueError, "Invalid access_code %r. Must be string of 1's and 0's" % (
                access_code, )
        self._preamble = preamble
        self._access_code = access_code
        self._pad_for_usrp = pad_for_usrp
        self._do_whitening = do_whitening
        self._add_crc = add_crc

        #create blocks
        msg_source = blocks.message_source(gr.sizeof_char, DEFAULT_MSGQ_LIMIT)
        self._msgq_out = msg_source.msgq()
        #initialize hier2
        gr.hier_block2.__init__(
            self,
            "cc1111_packet_encoder",
            gr.io_signature(0, 0, 0),  # Input signature
            gr.io_signature(1, 1, gr.sizeof_char)  # Output signature
        )
        #connect
        self.connect(msg_source, self)
コード例 #4
0
ファイル: packet.py プロジェクト: monikaomsharma/sandhi
    def __init__(self, access_code='', threshold=-1, callback=None):
        """
		packet_demod constructor.
		@param access_code AKA sync vector
		@param threshold detect access_code with up to threshold bits wrong (0 -> use default)
		@param callback a function of args: ok, payload
		"""
        #access code
        if not access_code:  #get access code
            access_code = packet_utils.default_access_code
        if not packet_utils.is_1_0_string(access_code):
            raise ValueError, "Invalid access_code %r. Must be string of 1's and 0's" % (
                access_code, )
        self._access_code = access_code
        #threshold
        if threshold < 0: threshold = DEFAULT_THRESHOLD
        self._threshold = threshold
        #blocks
        msgq = gr.msg_queue(DEFAULT_MSGQ_LIMIT)  #holds packets from the PHY
        correlator = digital.correlate_access_code_bb(self._access_code,
                                                      self._threshold)
        framer_sink = gr.framer_sink_1(msgq)
        #initialize hier2
        gr.hier_block2.__init__(
            self,
            "packet_decoder",
            gr.io_signature(1, 1, gr.sizeof_char),  # Input signature
            gr.io_signature(0, 0, 0)  # Output signature
        )
        #connect
        self.connect(self, correlator, framer_sink)
        #start thread
        _packet_decoder_thread(msgq, callback)
コード例 #5
0
ファイル: packet_framer.py プロジェクト: IzzyAbdullah/pre-cog
    def __init__(self, access_code=None, threshold=-1):
        """
        Create a new packet deframer.
        @param access_code: AKA sync vector
        @type access_code: string of 1's and 0's
        @param threshold: detect access_code with up to threshold bits wrong (-1 -> use default)
        @type threshold: int
        """

        gr.hier_block2.__init__(
            self,
            "demod_pkts2",
            gr.io_signature(1, 1, 1),
            gr.io_signature(1, 1, 1),
        )

        if not access_code:
            access_code = packet_utils.default_access_code
        if not packet_utils.is_1_0_string(access_code):
            raise ValueError, "Invalid access_code %r. Must be string of 1's and 0's" % (access_code,)

        if threshold == -1:
            threshold = 12              # FIXME raise exception

        msgq = gr.msg_queue(4)          # holds packets from the PHY
        self.correlator = gr_digital.correlate_access_code_bb(access_code, threshold)

        self.framer_sink = gr.framer_sink_1(msgq)
        self.connect(self, self.correlator, self.framer_sink)
        self._queue_to_blob = _queue_to_blob(msgq)
        self.connect(self._queue_to_blob, self)
コード例 #6
0
ファイル: packet.py プロジェクト: FOSSEE-Manipal/gnuradio
	def __init__(self, access_code='', threshold=-1, callback=None):
		"""
		packet_demod constructor.
		@param access_code AKA sync vector
		@param threshold detect access_code with up to threshold bits wrong (0 -> use default)
		@param callback a function of args: ok, payload
		"""
		#access code
		if not access_code: #get access code
			access_code = packet_utils.default_access_code
		if not packet_utils.is_1_0_string(access_code):
			raise ValueError, "Invalid access_code %r. Must be string of 1's and 0's" % (access_code,)
		self._access_code = access_code
		#threshold
		if threshold < 0: threshold = DEFAULT_THRESHOLD
		self._threshold = threshold
		#blocks
		msgq = gr.msg_queue(DEFAULT_MSGQ_LIMIT) #holds packets from the PHY
		correlator = digital.correlate_access_code_bb(self._access_code, self._threshold)
		framer_sink = gr.framer_sink_1(msgq)
		#initialize hier2
		gr.hier_block2.__init__(
			self,
			"packet_decoder",
			gr.io_signature(1, 1, gr.sizeof_char), # Input signature
			gr.io_signature(0, 0, 0) # Output signature
		)
		#connect
		self.connect(self, correlator, framer_sink)
		#start thread
		_packet_decoder_thread(msgq, callback)
コード例 #7
0
ファイル: packet.py プロジェクト: FOSSEE-Manipal/gnuradio
	def __init__(self, samples_per_symbol, bits_per_symbol, access_code='', pad_for_usrp=True):
		"""
		packet_mod constructor.
		@param samples_per_symbol number of samples per symbol
		@param bits_per_symbol number of bits per symbol
		@param access_code AKA sync vector
		@param pad_for_usrp If true, packets are padded such that they end up a multiple of 128 samples
		@param payload_length number of bytes in a data-stream slice
		"""
		#setup parameters
		self._samples_per_symbol = samples_per_symbol
		self._bits_per_symbol = bits_per_symbol
		self._pad_for_usrp = pad_for_usrp
		if not access_code: #get access code
			access_code = packet_utils.default_access_code
		if not packet_utils.is_1_0_string(access_code):
			raise ValueError, "Invalid access_code %r. Must be string of 1's and 0's" % (access_code,)
		self._access_code = access_code
		self._pad_for_usrp = pad_for_usrp
		#create blocks
		msg_source = gr.message_source(gr.sizeof_char, DEFAULT_MSGQ_LIMIT)
		self._msgq_out = msg_source.msgq()
		#initialize hier2
		gr.hier_block2.__init__(
			self,
			"packet_encoder",
			gr.io_signature(0, 0, 0), # Input signature
			gr.io_signature(1, 1, gr.sizeof_char) # Output signature
		)
		#connect
		self.connect(msg_source, self)
コード例 #8
0
ファイル: packet_framer.py プロジェクト: dzakwanfalih/gr-mac
 def __init__(
     self,
     msgq,
     access_code=None,
     threshold=0
     ):
     """
     Create a new packet deframer.
     @param access_code: AKA sync vector
     @type access_code: string of 1's and 0's
     @param threshold: detect access_code with up to threshold bits wrong
     @type threshold: int
     """
     gr.hier_block2.__init__(
         self,
         "packet_deframer",
         gr.io_signature(1, 1, 1),
         gr.io_signature(0, 0, 0)
     )
     
     if not access_code:
         access_code = packet_utils.default_access_code
     if not packet_utils.is_1_0_string(access_code):
         raise ValueError, "Invalid access_code %r. Must be string of 1's and 0's" % (access_code,)
     
     if threshold < 0:
         raise ValueError, "Invalid threshold value %d" % (threshold)
     
     #default_access_code = conv_packed_binary_string_to_1_0_string('\xAC\xDD\xA4\xE2\xF2\x8C\x20\xFC')
     #default_preamble = conv_packed_binary_string_to_1_0_string('\xA4\xF2')
     
     self.msgq = msgq
     self.correlator = gr_digital.correlate_access_code_bb(access_code, threshold)
     self.framer_sink = gr_digital.framer_sink_1(self.msgq)
     self.connect(self, self.correlator, self.framer_sink)
コード例 #9
0
    def __init__(self, callback=None):
        """
        packet_demod constructor.

        Args:
            station_id: The ID of the station that we are trying to decode the data from.
        """
        # access code
        self._threshold = DEFAULT_THRESHOLD
        access_code = STATION_CODES["default"]

        if not packet_utils.is_1_0_string(access_code):
            raise ValueError, "Invalid access_code %r. Must be string of 1's and 0's" % (
                access_code, )

        self._access_code = access_code

        # blocks
        msgq = gr.msg_queue(DEFAULT_MSGQ_LIMIT)  # holds packets from the PHY
        correlator = digital.correlate_access_code_bb(self._access_code,
                                                      self._threshold)
        framer_sink = digital.framer_sink_1(msgq)
        # initialize hier2
        gr.hier_block2.__init__(
            self,
            "packet_decoder",
            gr.io_signature(1, 1, gr.sizeof_char),  # Input signature
            gr.io_signature(0, 0, 0)  # Output signature
        )
        # connect
        self.connect(self, correlator, framer_sink)
        # start thread
        _packet_decoder_thread(msgq, callback)
コード例 #10
0
    def __init__(self,
                 samples_per_symbol,
                 bits_per_symbol,
                 access_code=None,
                 use_whitener_offset=False):
        """
        Create a new packet framer.
        @param access_code: AKA sync vector
        @type access_code: string of 1's and 0's between 1 and 64 long
        @param use_whitener_offset: If true, start of whitener XOR string is incremented each packet
        """

        self._bits_per_symbol = bits_per_symbol
        self._samples_per_symbol = samples_per_symbol

        gr.block.__init__(
            self,
            name="mod_pkts2",
            in_sig=None,
            out_sig=[numpy.uint8],
            has_msg_input=True,
        )

        self._use_whitener_offset = use_whitener_offset
        self._whitener_offset = 0

        if not access_code:
            access_code = packet_utils.default_access_code
        if not packet_utils.is_1_0_string(access_code):
            raise ValueError, "Invalid access_code %r. Must be string of 1's and 0's" % (
                access_code, )
        self._access_code = access_code
        self._pkt = []
        self.more_frame_cnt = 0
        self.keep = False
コード例 #11
0
    def __init__(self, access_code=None, threshold=-1):
        """
        Create a new packet deframer.
        @param access_code: AKA sync vector
        @type access_code: string of 1's and 0's
        @param threshold: detect access_code with up to threshold bits wrong (-1 -> use default)
        @type threshold: int
        """

        gr.hier_block2.__init__(
            self,
            "demod_pkts2",
            gr.io_signature(1, 1, 1),
            gr.io_signature(1, 1, 1),
        )

        if not access_code:
            access_code = packet_utils.default_access_code
        if not packet_utils.is_1_0_string(access_code):
            raise ValueError, "Invalid access_code %r. Must be string of 1's and 0's" % (
                access_code, )

        if threshold == -1:
            threshold = 12  # FIXME raise exception

        msgq = gr.msg_queue(4)  # holds packets from the PHY
        self.correlator = gr_digital.correlate_access_code_bb(
            access_code, threshold)

        self.framer_sink = gr.framer_sink_1(msgq)
        self.connect(self, self.correlator, self.framer_sink)
        self._queue_to_blob = _queue_to_blob(msgq)
        self.connect(self._queue_to_blob, self)
コード例 #12
0
    def __init__(
        self,
        samples_per_symbol,
        bits_per_symbol,
        access_code=None,
        use_whitener_offset=False
    ):
        """
        Create a new packet framer.
        @param access_code: AKA sync vector
        @type access_code: string of 1's and 0's between 1 and 64 long
        @param use_whitener_offset: If true, start of whitener XOR string is incremented each packet
        """

        self._bits_per_symbol = bits_per_symbol
        self._samples_per_symbol = samples_per_symbol

        gr.block.__init__(
            self,
            name = "mod_pkts2",
            in_sig = None,
            out_sig = [numpy.uint8],
            has_msg_input = True,
        )

        self._use_whitener_offset = use_whitener_offset
        self._whitener_offset = 0

        if not access_code:
            access_code = packet_utils.default_access_code
        if not packet_utils.is_1_0_string(access_code):
            raise ValueError, "Invalid access_code %r. Must be string of 1's and 0's" % (access_code,)
        self._access_code = access_code
        self._pkt = []
コード例 #13
0
    def __init__(self,
                 samples_per_symbol,
                 bits_per_symbol,
                 preamble='',
                 access_code='',
                 pad_for_usrp=True):
        """
        packet_mod constructor.
        
        Args:
            samples_per_symbol: number of samples per symbol
            bits_per_symbol: number of bits per symbol
            access_code: AKA sync vector
            pad_for_usrp: If true, packets are padded such that they end up a multiple of 128 samples
            payload_length: number of bytes in a data-stream slice

        """

        print "here1"
        gr.basic_block.__init__(self,
                                name="packet_encoder",
                                in_sig=[numpy.uint8],
                                out_sig=[numpy.uint8])
        #setup parameters
        self._samples_per_symbol = samples_per_symbol
        self._bits_per_symbol = bits_per_symbol
        self._pad_for_usrp = pad_for_usrp
        if not preamble:  #get preamble
            preamble = packet_utils.default_preamble
        if not access_code:  #get access code
            access_code = packet_utils.default_access_code
        if not packet_utils.is_1_0_string(preamble):
            raise ValueError, "Invalid preamble %r. Must be string of 1's and 0's" % (
                preamble, )
        if not packet_utils.is_1_0_string(access_code):
            raise ValueError, "Invalid access_code %r. Must be string of 1's and 0's" % (
                access_code, )

        self._preamble = preamble
        self._access_code = access_code
        self._pad_for_usrp = pad_for_usrp
        #create blocks
        msg_source = blocks.message_source(gr.sizeof_char, DEFAULT_MSGQ_LIMIT)
        self._msgq_out = msg_source.msgq()
コード例 #14
0
ファイル: cc1111_packet.py プロジェクト: drtyhlpr/gr-cc1111
	def __init__(self, samples_per_symbol, bits_per_symbol, preamble='', access_code='', pad_for_usrp=True, do_whitening=False, add_crc=False):
		"""
		packet_mod constructor.
        
		Args:
			samples_per_symbol: number of samples per symbol
			bits_per_symbol: number of bits per symbol
			access_code: AKA sync vector
			pad_for_usrp: If true, packets are padded such that they end up a multiple of 128 samples
			do_whitening: apply CC111x whitening
			add_crc: add CRC16 
		"""

		#setup parameters
		self._samples_per_symbol = samples_per_symbol
 		self._bits_per_symbol = bits_per_symbol
		self._pad_for_usrp = pad_for_usrp
		if not preamble: #get preamble
			preamble = cc1111_packet_utils.default_preamble
		if not access_code: #get access code
			access_code = cc1111_packet_utils.default_access_code
		if not packet_utils.is_1_0_string(preamble):
			raise ValueError, "Invalid preamble %r. Must be string of 1's and 0's" % (preamble,)
		if not packet_utils.is_1_0_string(access_code):
			raise ValueError, "Invalid access_code %r. Must be string of 1's and 0's" % (access_code,)
		self._preamble = preamble
		self._access_code = access_code
		self._pad_for_usrp = pad_for_usrp
		self._do_whitening = do_whitening
		self._add_crc = add_crc

		#create blocks
		msg_source = blocks.message_source(gr.sizeof_char, DEFAULT_MSGQ_LIMIT)
		self._msgq_out = msg_source.msgq()
		#initialize hier2
		gr.hier_block2.__init__(
			self,
			"cc1111_packet_encoder",
			gr.io_signature(0, 0, 0), # Input signature
			gr.io_signature(1, 1, gr.sizeof_char) # Output signature
		)
		#connect
		self.connect(msg_source, self)
コード例 #15
0
ファイル: wmbus_blocks.py プロジェクト: tdandrade/gr-wmbus
    def __init__(self, preamble="010101010", sync_word="0000111101"):
        """
        @param preamble: the preamble chips
        @param sync_word: the sync word bits
        """
        gr.hier_block2.__init__(
            self, "correlate_preamble",
            gr.io_signature(1, 1, gr.sizeof_char*1),
            gr.io_signature(1, 1, gr.sizeof_char*1),
        )

        if not packet_utils.is_1_0_string(preamble):
            raise ValueError, "Invalid access_code %r. Must be string of 1's and 0's" % (preamble,)
        self.preamble = digital.correlate_access_code_tag_bb(preamble, 0, "preamble")

        if not packet_utils.is_1_0_string(sync_word):
            raise ValueError, "Invalid access_code %r. Must be string of 1's and 0's" % (sync_word,)
        self.sync = digital.correlate_access_code_tag_bb(sync_word, 0, "sync")

        self.connect(self, self.sync, self.preamble, self)
コード例 #16
0
    def __init__(self):
        """
        packet_mod constructor.

        Args:
            station_id: The ID of the station transmitting the data.
        """
        # setup parameters
        self._samples_per_symbol = 1
        self._bits_per_symbol = 1
        self._pad_for_usrp = False

        access_code = STATION_CODES["default"]
        preamble = packet_utils.default_preamble + "1010110011011101101001001110001011110010100011000010000011111100"

        if not packet_utils.is_1_0_string(preamble):
            raise ValueError, "Invalid preamble %r. Must be string of 1's and 0's" % (
                preamble, )
        if not packet_utils.is_1_0_string(access_code):
            raise ValueError, "Invalid access_code %r. Must be string of 1's and 0's" % (
                access_code, )

        self._preamble = preamble
        self._access_code = access_code

        # create blocks
        msg_source = blocks.message_source(gr.sizeof_char, DEFAULT_MSGQ_LIMIT)
        self._msgq_out = msg_source.msgq()
        # initialize hier2
        gr.hier_block2.__init__(
            self,
            "packet_encoder",
            gr.io_signature(0, 0, 0),  # Input signature
            gr.io_signature(1, 1, gr.sizeof_char)  # Output signature
        )
        # connect
        self.connect(msg_source, self)
コード例 #17
0
ファイル: packet_framer.py プロジェクト: dzakwanfalih/gr-mac
    def __init__(
        self,
        #samples_per_symbol,
        #bits_per_symbol,
        access_code=None,
        whitener_offset=0,
        rotate_whitener_offset=False,
        whiten=True,
        preamble='',
        postamble=''
    ):
        """
        Create a new packet framer.
        @param access_code: AKA sync vector
        @type access_code: string of 1's and 0's between 1 and 64 long
        @param use_whitener_offset: If true, start of whitener XOR string is incremented each packet
        """
        gr.basic_block.__init__(
            self,
            name="packet_framer",
            in_sig=None,
            out_sig=None)
        
        self.message_port_register_out(pmt.intern('out'))
        self.message_port_register_in(pmt.intern('in'))
        self.set_msg_handler(pmt.intern('in'), self.packetise)
        
        if not access_code:
            access_code = packet_utils.default_access_code
        if not packet_utils.is_1_0_string(access_code):
            raise ValueError, "Invalid access_code %r. Must be string of 1's and 0's" % (access_code,)

        #self._bits_per_symbol = bits_per_symbol
        #self._samples_per_symbol = samples_per_symbol
        self.rotate_whitener_offset = rotate_whitener_offset
        self.whitener_offset = whitener_offset
        self.whiten = whiten
        self.access_code = access_code
        self.preamble = preamble
        self.postamble = postamble
コード例 #18
0
 def __init__(self,
              samples_per_symbol,
              bits_per_symbol,
              access_code='',
              pad_for_usrp=True):
     """
     packet_mod constructor.
     
     Args:
         samples_per_symbol: number of samples per symbol
         bits_per_symbol: number of bits per symbol
         access_code: AKA sync vector
         pad_for_usrp: If true, packets are padded such that they end up a multiple of 128 samples
         payload_length: number of bytes in a data-stream slice
     """
     #setup parameters
     self._samples_per_symbol = samples_per_symbol
     self._bits_per_symbol = bits_per_symbol
     self._pad_for_usrp = pad_for_usrp
     if not access_code:  #get access code
         access_code = packet_utils.default_access_code
     if not packet_utils.is_1_0_string(access_code):
         raise ValueError, "Invalid access_code %r. Must be string of 1's and 0's" % (
             access_code, )
     self._access_code = access_code
     self._pad_for_usrp = pad_for_usrp
     #create blocks
     msg_source = blocks.message_source(gr.sizeof_char, DEFAULT_MSGQ_LIMIT)
     self._msgq_out = msg_source.msgq()
     #initialize hier2
     gr.hier_block2.__init__(
         self,
         "packet_encoder",
         gr.io_signature(0, 0, 0),  # Input signature
         gr.io_signature(1, 1, gr.sizeof_char)  # Output signature
     )
     #connect
     self.connect(msg_source, self)