def pass_thread_address(self, main_thread, sensor_controller): try: self.main_thread = main_thread self.sensor_controller = sensor_controller logger.debug("Addresses of main_thread and sensor_controller saved.") except Exception as inst: logger.critical("ERROR: Exception in pass_thread_address: " + str(inst))
def initialize_handler_vector_table(self): try: self.handler_vector_table[self.reg_msg_handler_no] = self.reg_msg_handler self.handler_vector_table[self.data_msg_handler_no] = self.data_msg_handler logger.debug("Handler vector table initialized.") except Exception as inst: logger.critical("ERROR: Exception in initialize_handler_vector_table: " + str(inst) )
def reg_msg_handler(self, msg_info, reply=None): try: logger.debug("Registration msg handler called.") if reply: for single_response in reply.payloads: if single_response.return_value == 0: logger.info("\t\tRegistration ACK received.") # change status to YES in config file config = ConfigObj(config_file_name) config["Registered"] = "YES" config["UTC Time"] = single_response.output bashit("date -s@"+str(single_response.output)) config.write() start_communication_with_nc_event.set() logger.info("Start_communication_with_nc_event is set.") else: logger.critical("ERROR: Unknown ACK received: Discarding..") return # handle failure logger.critical("Registration timeout.............") msg_info[2] = self.calculate_expiration_time(registration_type, None) self.add_to_sent_msgs_bfr(msg_info) self.send_msg_to_nc(msg_info[3]) logger.critical("Registration msg resent.............") except Exception as inst: logger.critical("ERROR: Exception in reg_msg_handler: " + str(inst))
def run(self): try: logger.debug("Starting " + self.thread_name ) if not self.communicator_thread_started: self.external_communicator = external_communicator_class("external_communicator", self.nc_port, self) self.external_communicator.start() self.communicator_thread_started = 1 wait_time_set = 0 while True: while (not self.outgoing_gnMsgBfr.empty()) or (self.sent_gnMsgBfr) or (not self.incoming_ncAckBfr.empty()): self.send_in_to_out_msg() self.process_out_to_in_msg() self.send_timed_out_msg() time.sleep(0.0001) wait_time_set=0 else: if wait_time_set==0: wait_time = time.time() + wait_time_for_next_msg wait_time_set=1; if wait_time > time.time(): time.sleep(0.0001) else: time.sleep(0.1) except Exception as inst: logger.critical("ERROR: Exception in bufr_mngr run: " + str(inst) ) if not self.external_communicator.isAlive(): logger.critical("External Communicator dead.") self.communicator_thread_started = 0 logger.critical("Waiting for socket to get closed.") time.sleep(2) else: logger.critical("External Communicator not dead.") time.sleep(10) self.run()
def register_gn(self): logger.debug("Checking whether registration is done or not." + "\n\n") # if self.check_registration_status(): ## Registration already done so just send msg to NC saying that I am up # self.send_ready_notification() # else: self.send_GN_registration_request()
def process_out_to_in_msg(self): try: if not self.incoming_ncAckBfr.empty(): item = self.incoming_ncAckBfr.get() logger.debug("Msg from NCR:" + str(item.msg) ) try: decoded_msg = Message.decode(item.msg) except Exception as inst: logger.critical("ERROR: Exception while decoding msg: " + str(inst) ) logger.critical("So discarding msg............." + str(inst) ) self.incoming_ncAckBfr.task_done() return # check whether the msg is new or duplicate if self.new_msg(decoded_msg): # when an ACK is obtained delete the corresponding waiting msg if decoded_msg.header.message_type == reply_type: session_id = self.convert_to_int(decoded_msg.header.reply_to_id[:self.seq_no_partition_size]) subseq_no = self.convert_to_int(decoded_msg.header.reply_to_id[self.seq_no_partition_size:]) msg_info = self.get_and_del_saved_msg(session_id, subseq_no) self.handler_vector_table[msg_info[4]](msg_info, decoded_msg) else: logger.critical("OLD MSG DISCARDED.............") self.incoming_ncAckBfr.task_done() except Exception as inst: logger.critical("ERROR: Exception in process_out_to_in_msg: " + str(inst) )
def gen_gn_seq_no(self): try: self.highest_gn_subseq_no = self.increment_no(self.highest_gn_subseq_no) logger.debug("\tSUBSEQUENCE NO. gen:" + str(self.highest_gn_subseq_no)) return str(self.convert_to_bytearray(self.gn_session_id)) +\ str(self.convert_to_bytearray(self.highest_gn_subseq_no)) except Exception as inst: logger.critical("ERROR: Exception in gen_gn_seq_no: " + str(inst))
def collect_incoming_data(self, data): try: if self.shutdown == 0: """Buffer the data""" self.input_buffer.append(data) logger.debug("Data received from NC.\n\n") except Exception as inst: logger.critical("Exception in collect_incoming_data: " + str(inst) + "\n\n")
def add_to_sent_msgs_bfr(self, msg_handler_info): try: logger.debug("Buffer size of GN_msgs_buffer_mngr's output buffer \ before adding item: " + str(len(self.sent_gnMsgBfr))) self.sent_gnMsgBfr.append(msg_handler_info) # sorted based on time so retrieval for expired msgs is in FIFO order sorted(self.sent_gnMsgBfr, key=lambda x: x[2]) logger.debug("Msg waiting for ACK inserted in sorted buffer.") except Exception as inst: logger.critical("ERROR: Exception in add_to_sent_msgs_bfr: " + str(inst) )
def __init__(self, thread_name): threading.Thread.__init__(self) # can be used by logging module for printing messages related to this thread self.thread_name = thread_name self.daemon = True self.sensor_dataMsgs = Queue.Queue(maxsize=1000) self.main_thread = '' self.buffer_mngr = '' self.sensor_msg_delimiter = str(unichr(12)) logger.debug("Thread "+self.thread_name+" Initialized."+ "\n\n")
def get_msg_handler_no(self, msg_type): try: if msg_type == registration_type: logger.debug("Fetching registration msg handler no.") return self.reg_msg_handler_no elif msg_type == data_type: logger.debug("Fetching data msg handler no.") return self.data_msg_handler_no except Exception as inst: logger.critical("ERROR: Exception in get_msg_handler_no: " + str(inst))
def calculate_expiration_time(self, msg_type, msg): try: if msg_type == registration_type: wait_time = gn_registration_ack_wait_time elif msg_type == data_type: wait_time = data_ack_wait_time logger.debug("Calculated expiration_time based on msg_type and msg.") return (time.time() + wait_time) except Exception as inst: logger.critical("ERROR: Exception in calculate_expiration_time: " + str(inst))
def __init__(self, thread_name, nc_port): # can be used by logging module for printing messages related to this thread self.thread_name = thread_name self.reg_msg_handler_no = 0 self.update_handler_no = 1 self.status_handler_no = 2 self.input_buffer = Queue.Queue(maxsize=1000) self.nc_port = nc_port self.sensor_controller = "" self.buffer_mngr = "" logger.debug("info Thread " + self.thread_name + " Initialized." + "\n\n")
def start_sensors(self, sensor_class_objcts, sensor_class_names): try: config = ConfigObj(config_file_name) for sensor_class_obj, sensor_class_name in zip(sensor_class_objcts, sensor_class_names): t = Thread(target=self.start_sensor, args = (sensor_class_obj, \ self.sensorBoard_input_queue[sensor_class_name], self.sensorBoard_output_queue[sensor_class_name])) self.update_sensor_thread_list(t) t.start() logger.debug("New sensors started."+"\n\n") except Exception as inst: logger.critical("Exception in start_sensors: " + str(inst)+"\n\n")
def extract_module_names(self, module_list): try: module_names = [] for module in module_list: if not os.path.isdir(module): module = module.split('.') if self.is_source_module(module) and self.is_new_module(module[0]): module_names.append(module[0]) logger.debug("New module names extracted."+"\n\n") return module_names except Exception as inst: logger.critical("Exception in extract_module_names: " + str(inst)+"\n\n")
def initialize_gn_session_id(self): try: session_id = self.get_old_session_id('GN Session ID') if not session_id: session_id = self.initial_session_id session_id = int (session_id) session_id = self.increment_no(session_id) self.save_session_id("GN Session ID", session_id) logger.debug("Seq_no. initialized.") return session_id except Exception as inst: logger.critical("ERROR: Exception in initialize_gn_session_id: " + str(inst) )
def handle_request(self): try: msg = '' if self.shutdown == 0: # recreates msg by concatenating list's elements for single_msg in self.input_buffer: msg = msg + single_msg msg = buffered_msg(None, None, None, msg) # Sends msg to the buffer_mngr's buffer add_to_thread_buffer(self.buffer_mngr.incoming_ncAckBfr, msg, "Buffer Mngr") logger.debug("Msg forwarded to buffer_mngr.\n\n") except Exception as inst: logger.critical("Exception in handle_request: " + str(inst) + "\n\n")
def store_node_info(self): try: if os.path.exists(config_file_name): config = ConfigObj(config_file_name) if config["Systems Info"] != {}: # gn.cfg is already present return else: initialize_config_file(config_file_name) ret_val = get_node_info(config_file_name) logger.debug("System's Info stored in config file." + "\n\n") except Exception as inst: logger.critical("Exception in store_node_info: " + str(inst) + "\n\n")
def found_terminator(self): try: if self.shutdown == 0: # logger.critical("Msg received from NC:"+str('%0.4f' % time.time())\ # +str(self.input_buffer)+"\n\n") #+ logger.critical("Msg received from NC:"+str('%0.4f' % time.time())\ + "<<<<<<<<<<<<<<<<<<<<") self.handle_request() logger.debug("Msg handled.\n\n") self.input_buffer = [] else: logger.critical("Socket is closed.\n\n") except Exception as inst: logger.critical("Exception in found_terminator: " + str(inst) + "\n\n")
def send_GN_registration_request(self): # This event is set by sensor_controller after it stores the sensors' info in config file logger.debug("Waiting for sensors info." + "\n\n") # Waits till sensor_plugin object finishes writing to the config file # so that race conditions don't occur sensors_info_saved_event.wait() config = ConfigObj(config_file_name) temp_config = {} temp_config["Systems Info"] = config["Systems Info"] temp_config["Sensors Info"] = config["Sensors Info"] reg_payload = RegistrationPayload() reg_payload.sys_info = dict(temp_config) reg_payload.instance_id = get_instance_id() self.send_to_buffer_mngr(registration_type, no_reply, [reg_payload])
def __init__(self, thread_name, nc_port): try: threading.Thread.__init__(self) # can be used for tagging the msgs related to this thread self.thread_name = thread_name self.daemon = True ############################### """ # Below are different types of buffers """ self.outgoing_gnMsgBfr = Queue.Queue(maxsize=1000) self.incoming_ncAckBfr = Queue.Queue(maxsize=1000) # Stores only sent reg/data/cmds not replies/ACKs self.sent_gnMsgBfr =[] ############################### # Port where NC listens for GNs self.nc_port = nc_port self.main_thread_ = '' self.sensor_controller = '' self.external_communicator = '' self.log_file_name = 'session_ids' self.communicator_thread_started = 0 self.reg_msg_handler_no = 0 self.data_msg_handler_no = 1 self.handler_vector_table = {} self.initialize_handler_vector_table() # Default for session_id/last_subseq_no/ackd_subseq_no and mean nothing self.default_seq_no = 0 self.error_scope = 255 self.upper_seq_bytes_limit = 16777215 # Specifies the no of bytes after which the subseq_no starts self.seq_no_partition_size = 3 self.initial_session_id = self.default_seq_no self.gn_session_id = self.initialize_gn_session_id() self.nc_session_id = self.default_seq_no # subseq_no of the last msg (excluding duplicate) sent to NC self.highest_gn_subseq_no = self.default_seq_no # subseq_no of the last msg (excluding duplicate) sent to GN self.highest_nc_subseq_no = self.default_seq_no # subseq_no of the last msg of GN (excluding duplicate) acknowledged by NC self.ackd_gn_subseq_no = self.default_seq_no # subseq_no of the last msg of NC (excluding duplicate) acknowledged by GN self.ackd_nc_subseq_no = self.default_seq_no # currently all tests are done using same window_size for GN and NC self.gn_window_size = 1 self.nc_window_size = 1 logger.debug("Thread "+self.thread_name+" Initialized.") except Exception as inst: logger.critical("ERROR: Exception in init function: " + str(inst))
def send_data_msg(self, item): data_payload = DataPayload() data_payload.sens_id = item.msg[0] data_payload.read_tm = item.msg[1] data_payload.inst_id = get_instance_id() ret = True for reading_name, reading_type, reading_value, reading_unit, reading_note in\ zip(item.msg[2], item.msg[3], item.msg[4], item.msg[5], item.msg[6]): ret = (ret and data_payload.add_item(reading_name, reading_type, \ reading_value, reading_unit, reading_note)) if not ret: logger.critical("Error in packing data....................................") logger.debug("DATA PAYLOAD:" + str(data_payload) + "\n\n") self.send_to_buffer_mngr(data_type, item.reply_id, [data_payload]) logger.debug("Data msg sent to bufr mngr to send to NC." + "\n\n")
def __init__(self, thread_name, nc_port, buffer_mngr): threading.Thread.__init__(self) # can be used by logging module for printing messages related to this thread self.thread_name = thread_name self.daemon = True # Static port where NC listens and where connection request can be sent self.nc_port = nc_port asynchat.async_chat.__init__(self) self.input_buffer = [] self.output_buffer = "" self.buffer_mngr = buffer_mngr # Used to signal that the NC is down so stop receiving. At present there is no # way to signal to stop sending to asynchat when NC is down, asynchat buffers msgs # in the output_buffer until connection is restablished self.shutdown = 0 self.set_terminator(asynchat_msg_terminator) logger.debug("Thread "+self.thread_name+" Initialized.\n\n")
def data_msg_handler(self, msg_info, reply=None): try: logger.debug("Data msg handler called.") if reply: for single_response in reply.payloads: if single_response.output == acknowledgment and not single_response.return_value: logger.info("\t\tData ACK received.") else: logger.critical("Unknown ACK received: Discarding..") return # handle failure logger.critical("Data Packet timeout.............") msg_info[2] = self.calculate_expiration_time(data_type, None) self.add_to_sent_msgs_bfr(msg_info) self.send_msg_to_nc(msg_info[3]) logger.critical("Data msg resent.............") except Exception as inst: logger.critical("ERROR: Exception in data_msg_handler: " + str(inst))
def send_in_to_out_msg(self): try: if not self.outgoing_gnMsgBfr.empty() and not self.is_sent_gnMsgBfr_full(): item = self.outgoing_gnMsgBfr.get() encoded_msg = self.gen_msg(item) encoded_msg = encoded_msg + asynchat_msg_terminator # save the copy of msg in sent_msgs buffer # send only if its not a reply (currently only reg/data msgs are present in the bfr) expiration_time = self.calculate_expiration_time(item.msg_type, item.msg) msg_handler_no = self.get_msg_handler_no(item.msg_type) unacknowledged_msg_handler_info = [self.gn_session_id,\ self.highest_gn_subseq_no, expiration_time, encoded_msg, msg_handler_no] logger.debug("Buffer size of buffer_mngr's output buffer\ before adding item: " + str(len(self.sent_gnMsgBfr))) self.add_to_sent_msgs_bfr(unacknowledged_msg_handler_info) logger.debug("Msg waiting for ACK inserted in sorted buffer.") self.send_msg_to_nc(encoded_msg) self.outgoing_gnMsgBfr.task_done() except Exception as inst: logger.critical("ERROR: Exception in send_in_to_out_msg: " + str(inst) )
def plugin_sensors(self): try: imported_sensor_modules, sensor_class_names = self.import_new_sensor_modules() logger.debug("Module extracted from package."+"\n\n") if sensor_class_names: sensor_class_objcts = [] for module_name, sensor_class_name in zip(imported_sensor_modules, sensor_class_names): if sensor_class_name != '__init__': try: # Loads the class dynamically from the imported module # So essentially the sensor_class_name (class name)\ # and the module_name (file name) must match sensor_class = getattr(module_name, sensor_class_name) # create an object of the above class sensor_class_obj = sensor_class() sensor_class_objcts.append(sensor_class_obj) except Exception as inst: logger.critical("Exception in plugin loop: " + str(inst)+"\n\n") self.register_modules(sensor_class_objcts, sensor_class_names) for sensor_class_name in sensor_class_names: self.sensorBoard_input_queue[sensor_class_name] = Queue.Queue() self.sensorBoard_output_queue[sensor_class_name] = Queue.Queue() logger.debug("Sensors' info added to the config file and their buffers created.") self.start_sensors(sensor_class_objcts, sensor_class_names) # Notify to the other threads that the sensors' info has been \ # saved in config file. Used to avoid race conditions. if not sensors_info_saved_event.is_set(): sensors_info_saved_event.set() logger.debug("Sensors_info_saved_event set."+"\n\n") return except Exception as inst: logger.critical("Exception in plugin_sensors: " + str(inst)+"\n\n")
def run(self): try: nc_ip = self.get_nc_ip() logger.debug("Starting " + self.thread_name + "\n\n") self.shutdown = 0 self.create_socket(socket.AF_INET, socket.SOCK_STREAM) self.connect( (nc_ip, self.nc_port) ) logger.info("CONNECTED............."+"\n\n") while True: # Starts the loop which polls the open socket for *count* times, # comes out of the asyncore loop and then repeats after 0.01s # Performance widely varies based on sleep time and count's value # When count=0/None control will never come out of the asyncore loop asyncore.loop(timeout=0.01, use_poll=True, map=None) # , count=n) can be added. n>=1 time.sleep(0.01) except Exception as inst: logger.critical("Exception in run: " + str(inst) + "\n\n") self.shutdown = 1 self.handle_close() logger.critical("Error in connecting with the NC.\n\n") time.sleep(10) self.run()
def run(self): try: logger.debug("Starting " + self.thread_name + "\n\n") self.store_node_info() self.sensor_controller = sensor_controller_class("sensor_controller") self.buffer_mngr = buffer_mngr_class("buffer_mngr", self.nc_port) self.sensor_controller.pass_thread_address(self, self.buffer_mngr) self.buffer_mngr.pass_thread_address(self, self.sensor_controller) self.sensor_controller.start() self.buffer_mngr.start() logger.critical("All threads started:" + str("%0.4f" % time.time()) + "\n\n") self.register_gn() wait_time = time.time() + wait_time_for_next_msg wait_time_set = 1 while True: time.sleep(0.1) # while (not self.input_buffer.empty()): # item = self.input_buffer.get() # logger.debug("Msg received in buffer:"+str(item)+ "\n\n") # process_external_msg(item) # else: # logger.critical("Unknown Msg Received: Discarding the msg\ # ............." + "\n\n") # self.input_buffer.task_done() ## set time to remain attentive for next 200 ms # wait_time = time.time() + wait_time_for_next_msg # time.sleep(0.0001) # if wait_time > time.time(): # time.sleep(0.0001) # else: # time.sleep(1) except Exception as inst: logger.critical("Exception in main_class: " + str(inst) + "\n\n") finally: self.sensor_controller.close() self.sensor_controller.join(1) self.buffer_mngr.close() self.buffer_mngr.join(1) logger.critical("All child threads exited. Parent Exiting..." + "\n\n")
def get_sensor_msgs(self): try: for each_sensor in self.sensorBoard_output_queue: while not self.sensorBoard_output_queue[each_sensor].empty(): item = self.sensorBoard_output_queue[each_sensor].get() msg_type = data_type reply_id = no_reply # Check whether sensor is properly registered or not if item[0] in self.registered_sensors: msg = item #print msg add_to_thread_buffer(self.sensor_dataMsgs, \ buffered_msg(msg_type, None, reply_id, msg), "Sensor Controller") self.sensorBoard_output_queue[each_sensor].task_done() logger.debug("Msg sent to sensor_dataMsgs." + str(msg)+"\n\n") elif item[0] not in self.registered_sensors: for i in range(1,6): item[i] = None item[6] = "Error in registering sensor." logger.critical("Error in registering sensor.") logger.debug("Msg sending to sensor_controller's buffer done."+"\n\n") except Exception as inst: logger.critical("Exception in get_sensor_msgs: " + str(inst)+"\n\n")
def process_msg(self): item = self.sensor_dataMsgs.get() logger.debug('Msg being processed..'+ "\n\n") # If the bfr_for_in_to_out_msgs is empty or msg to be # sent is a reply type then process the msg logger.debug('Received sensor msg.'+ "\n\n") self.send_data_msg(item) self.sensor_dataMsgs.task_done() logger.debug("Length of input bfr of sensor_controller:"+str(self.sensor_dataMsgs.qsize()))