//***************************************************************************************
LOG_MODULE_REGISTER(bms_module, CONFIG_BMS_MODULE_LOG_LEVEL);
//********************************************************
struct bms_msg_data {
	union {
		struct app_module_event app;
	} module;
};
/* BMS module super states. */
static enum state_type {
	BMS_INIT,
        BMS_DETECT,
	BMS_RUNNING,
} state;
/* Bms module message queue. */
#define BMS_QUEUE_ENTRY_COUNT	10
#define BMS_QUEUE_BYTE_ALIGNMENT 4

K_MSGQ_DEFINE(msgq_bms, sizeof(struct bms_msg_data),
	      BMS_QUEUE_ENTRY_COUNT, BMS_QUEUE_BYTE_ALIGNMENT);

static struct module_data self = {
	.name = "bms_DALY",
	.msg_q = &msgq_bms,
	.supports_shutdown = true,
};
/* Convenience functions used in internal state handling. */
static char *state2str(enum state_type new_state)
{
	switch (new_state) {
	case BMS_INIT:
              return "STATE_INIT";
        case BMS_DETECT:
              return "BMS DETECTED";
	case BMS_RUNNING:
              return "STATE_RUNNING";
	default:
		return "Unknown";
	}
}

static void state_set(enum state_type new_state)
{
	if (new_state == state) {
		LOG_DBG("State: %s", state2str(state));
		return;
	}

	LOG_DBG("State transition %s --> %s",
		state2str(state),
		state2str(new_state));

	state = new_state;
}
/* Handlers */
static bool app_event_handler(const struct app_event_header *eh)
{
  struct bms_msg_data msg = {0};
	bool enqueue_msg = false;

	if (is_app_module_event(eh)) {
		struct app_module_event *event = cast_app_module_event(eh);

		msg.module.app = *event;
		enqueue_msg = true;
	}    

	if (enqueue_msg) {
		int err = module_enqueue_msg(&self, &msg);

		if (err) {
			LOG_ERR("Message could not be enqueued");
			SEND_ERROR(bms, BMS_DATA_ERROR, err);
		}
	}

	return false;
}
/* Message handler for STATE_INIT. */
static void on_state_init(struct bms_msg_data *msg)
{   int ret;
    struct bms_module_event *bms_init_event = new_bms_module_event();

    if (IS_EVENT(msg, app, APP_EVT_START)){
    // my code here
    
    if((detect_pin_flag == true)&&(reset_pin_flag == true)){bms_init_event->type=BMS_PIN_SUCCESS;state_set(BMS_DETECT);}
        else{bms_init_event->type=BMS_PIN_FAIL;}

    EVENT_SUBMIT(bms_init_event);
   }
}
static void detect_bms(struct bms_msg_data *msg)
{
  struct bms_module_event *bms_detect_event = new_bms_module_event();
    if(IS_EVENT(msg, app, APP_EVT_CONFIG_GET)) 
 {
  // my code
  if(....)bms_detect_event->type = BMS_ATTACHED;
  else{bms_detect_event->type = BMS_DETACHED;}
 }
  EVENT_SUBMIT(bms_detect_event);
}
/* Message handler for STATE_RUNNING. */
static void on_state_running(struct bms_msg_data *msg)
{
  struct bms_module_event *bms_run_event = new_bms_module_event();
   if (IS_EVENT(msg, app, APP_EVT_DATA_GET)){
     // my code
     bms_run_event->type = BMS_DATA_READY;
   }  
   EVENT_SUBMIT(bms_run_event);
}
static void module_thread_fn(void)
{
        int err;
	struct bms_msg_data msg;

	self.thread_id = k_current_get();

	err = module_start(&self);
	if (err) {
		LOG_ERR("Failed starting module, error: %d", err);
		SEND_ERROR(bms, BMS_DATA_ERROR, err);
	}
        LOG_DBG("BMS Thread Started: %d", err);

        while (true) {
		module_get_next_msg(&self, &msg);
                LOG_WRN("New Message in BMS Thread");
          switch (state) {
		case BMS_INIT:
			on_state_init(&msg);
			break;
                case BMS_DETECT:
                        detect_bms(&msg);
                        break;
		case BMS_RUNNING:
			on_state_running(&msg);
			break;
		default:
			LOG_WRN("Unknown BMS module state.");
			break;
		}
        }
}
//*******************************************************************
K_THREAD_DEFINE(bms_module_thread, CONFIG_BMS_THREAD_STACK_SIZE,
		module_thread_fn, NULL, NULL, NULL,
		K_LOWEST_APPLICATION_THREAD_PRIO, 0, 0);
//*******************************************************************
APP_EVENT_LISTENER(MODULE, app_event_handler);
APP_EVENT_SUBSCRIBE(MODULE, app_module_event);
//*******************************************************************