Exemple #1
0
static int8_t handle_loader_ls_on_node( Message *msg )
{
	msg_ls_reply_t *reply;
	uint8_t i;

	reply = (msg_ls_reply_t *) ker_malloc( sizeof( msg_ls_reply_t ),
			KER_DFT_LOADER_PID );
	if( reply == NULL ) return -ENOMEM;

	for( i = 0; i < NUM_LOADER_PARAMS_ENTRIES; i ++ ) {
		sos_cam_t key = ker_cam_key( KER_DFT_LOADER_PID, i );
		loader_cam_t *cam;
		uint8_t buf[2];

		cam = ker_cam_lookup( key );
		if( cam != NULL && cam->fetcher.status == FETCHING_DONE 
				&& (ker_codemem_read( cam->fetcher.cm, KER_DFT_LOADER_PID, 
						buf, 2, 0) == SOS_OK)) {
			DEBUG_PID( KER_DFT_LOADER_PID, "Data(%d) = %d %d\n", i, buf[0], buf[1]);
			reply->pam_dst_pid[ i ] = buf[0];
			reply->pam_dst_subpid[ i ] = buf[1];
		} else {
			DEBUG_PID( KER_DFT_LOADER_PID, "Data(%d) = NULL\n", i);
			/*
			if( cam != NULL && cam->fetcher.status == FETCHING_DONE) {
				DEBUG_PID( KER_DFT_LOADER_PID, "ker_codemem_read failed...\n");
			}
			*/
			reply->pam_dst_pid[ i ] = NULL_PID;
			reply->pam_dst_subpid[ i ] = 0;
		}
	}
	for( i = 0; i < NUM_LOADER_MODULE_ENTRIES; i ++ ) {
		sos_cam_t key = ker_cam_key( KER_DFT_LOADER_PID, 
				NUM_LOADER_PARAMS_ENTRIES + i );
		loader_cam_t *cam;

		cam = ker_cam_lookup( key );

		if( cam != NULL && cam->fetcher.status == FETCHING_DONE ) {
			mod_header_ptr p;
			sos_code_id_t cid;
			// Get the address of the module header
			p = ker_codemem_get_header_address( cam->fetcher.cm );
			cid = sos_read_header_word( p, offsetof(mod_header_t, code_id));
			// warning: already netowrk order...
			reply->code_id[ i ] = cid;
		} else {
			reply->code_id[ i ] = 0;
		}
	}
	post_auto( KER_DFT_LOADER_PID,
			KER_DFT_LOADER_PID,
			MSG_LOADER_LS_REPLY,
			sizeof( msg_ls_reply_t ),
			reply,
			SOS_MSG_RELEASE,
			msg->saddr);
	return SOS_OK;
}
Exemple #2
0
static inline void handle_request_timeout()
{
	if(fst == NULL) {
		return;
	}
	//sos_assert(fst != NULL);
	//DEBUG("handle request timeout, retx = %d\n", fst->retx);
	fst->retx++;
	if(fst->retx <= FETCHER_REQUEST_MAX_RETX) {
		fetcher_bitmap_t *m;
		uint8_t size = sizeof(fetcher_bitmap_t) + fst->map.bitmap_size;

		DEBUG_PID(KER_FETCHER_PID,"send request to %d\n", fst->src_addr);
		print_bitmap(&fst->map);

		m = (fetcher_bitmap_t *) ker_malloc( size, KER_FETCHER_PID);
		if( m != NULL ) {
			memcpy(m, &(fst->map), size);
			m->key = ehtons( m->key );
			post_auto(KER_FETCHER_PID,
					KER_FETCHER_PID,
					MSG_FETCHER_REQUEST,
					size,
					m,
					SOS_MSG_RELEASE,
					fst->src_addr);
		}
		restart_request_timer();
	} else {
		DEBUG_PID(KER_FETCHER_PID, "request failed!!!\n");
		//codemem_close(&fst->cm, false);
		send_fetcher_done();
	}
}
Exemple #3
0
static int8_t handle_request(Message *msg)
{
	int8_t ret;
	//! setup a periodic timer to send fragments
	if(send_state.map == NULL) {
		fetcher_bitmap_t *b = (fetcher_bitmap_t*) msg->data;
		ret = set_num_funcs_in_send_state(b->key);
		if( ret != SOS_OK ) {
			// cannot find num funcs, give up
			return SOS_OK;
		}
		ret = ker_timer_restart(KER_FETCHER_PID,
				FETCHER_TRANSMIT_TID,
				FETCHER_SENDING_FRAGMENT_INTERVAL);
		if(ret == SOS_OK) {
			send_state.map = (fetcher_bitmap_t*)ker_msg_take_data(KER_FETCHER_PID, msg);
			send_state.dest = msg->saddr;
			DEBUG_PID(KER_FETCHER_PID,"send_state.map = 0x%x send_state.dest = 0x%x\n", (int)send_state.map, send_state.dest);
		} else {
			return -ENOMEM;
		}
	} else {
		fetcher_bitmap_t *map = (fetcher_bitmap_t*)msg->data;

		//! XXX change to broadcast
		//send_state.dest = BCAST_ADDRESS;
		DEBUG_PID(KER_FETCHER_PID,"else send_state.dest = %x\n", send_state.dest);
		//! merge wanted list
		if((send_state.map->key == map->key)) {
			uint8_t i;
			for(i = 0; i < send_state.map->bitmap_size &&
					i < map->bitmap_size; i++) {
				send_state.map->bitmap[i] |= map->bitmap[i];
			}

		}
	}

	if( fst != NULL && (fst->map.key == send_state.map->key) ) {
		//! send only those we have
		uint8_t i;
		for(i = 0; i < send_state.map->bitmap_size; i++ ) {
			uint8_t tmp;
			//! this is the fragment that has been requested but we dont have
			tmp = send_state.map->bitmap[i] & fst->map.bitmap[i];
			send_state.map->bitmap[i] &= ~tmp;
		}
	}
	return SOS_OK;
}
Exemple #4
0
static int8_t handle_data(Message *msg)
{
	fetcher_fragment_t *f;
	int8_t ret = -EINVAL;
	fetcher_cam_t *cam;

	f = (fetcher_fragment_t*)msg->data;

	DEBUG_PID(KER_FETCHER_PID, "fetcher: get data, key = %d, frag_id = %d\n", f->key, f->frag_id);
	//msg_print(msg);

	if(f->key != fst->map.key) {
		DEBUG_PID(KER_FETCHER_PID,"version mis-match\n");
		return SOS_OK;
	}

	cam = (fetcher_cam_t *) ker_shm_get( KER_FETCHER_PID, f->key);
	if( cam == NULL ) {
		// XXX cannot find CAM...
		// TODO: need to inform upper layer...
		return -EINVAL;
	}
	if( (fst->map.bitmap[(f->frag_id) / 8] & (1 << ((f->frag_id) % 8))) == 0 ) {
		// we already have the fragment...
		return SOS_OK;
	}

	if((f->frag_id != 0) && ((fst->map.bitmap[0] & 0x01) != 0)
		&& (cam->fetchtype == FETCHTYPE_MODULE)) {
		// if the first fragment is not available, we drop the packet
		return SOS_OK;
	}

	ret = ker_codemem_write(cam->cm, KER_FETCHER_PID,
			f->fragment, FETCHER_FRAGMENT_SIZE,
			(code_addr_t)FETCHER_FRAGMENT_SIZE * f->frag_id);
	if(ret == SOS_SPLIT) {
		send_state.fragr = (fetcher_fragment_t*) ker_msg_take_data(KER_FETCHER_PID, msg);	
		f = send_state.fragr;
	} else if(ret != SOS_OK) {
		//DEBUG("codemem_write failed\n");
		return SOS_OK;
	}

	fst->map.bitmap[(f->frag_id) / 8] &= ~(1 << ((f->frag_id) % 8));
	check_map_and_post();
	return SOS_OK;
}
Exemple #5
0
int8_t ker_timer_start(sos_pid_t pid, uint8_t tid, int32_t interval)
{
  sos_timer_t* tt;
  //! Start the timer from the timer pool
  tt = alloc_from_timer_pool(pid, tid);
  
  //! If the timer does not exist, then it is already in use or not initialized
  if (tt == NULL) {
	DEBUG_PID(TIMER_PID, "ker_timer_start: tt == NULL\n");
	return -EINVAL;
  }
  
  //  tt->ticks = PROCESSOR_TICKS(interval);
  tt->ticks = interval;
  tt->delta = interval;
  
  //DEBUG("timer_start(%d) %d %d %d\n", tt->pid, tt->tid, tt->type, tt->ticks);
  
  //! insert into delta queue
  print_all_timers("timer_start_start");
  timer_delta_q_insert(tt, true);
  print_all_timers("timer_start_end");
  ker_log( SOS_LOG_TIMER_START, pid, tid );
  return SOS_OK;
}
Exemple #6
0
int8_t fetcher_request(sos_pid_t req_id, sos_shm_t key, uint16_t size, uint16_t src)
{
    uint8_t bitmap_size;   //! size of the bitmap in bytes
    uint16_t num_fragments;
    uint8_t i;
    fetcher_state_t *f;
	fetcher_cam_t *cam;
	
	cam = (fetcher_cam_t *) ker_shm_get( KER_FETCHER_PID, key);
	if( cam == NULL ) return -EINVAL;

    //if(fst != NULL) return -EBUSY;
    DEBUG_PID(KER_FETCHER_PID, "fetcher_request, req_id = %d, size = %d, src = %d\n", req_id, size, src);

    num_fragments = ((size + (FETCHER_FRAGMENT_SIZE - 1))/ FETCHER_FRAGMENT_SIZE);
    bitmap_size = (uint8_t)((num_fragments + 7)/ 8);

    //DEBUG("size = %d\n", sizeof(fetcher_state_t) + bitmap_size);
    f = ker_malloc(sizeof(fetcher_state_t) + bitmap_size, KER_FETCHER_PID);
    if(f == NULL) {
        return -ENOMEM;
    }
    //DEBUG("num_fragments = %d, bitmap_zie = %d\n", num_fragments, bitmap_size);
    f->requester       = req_id;
    f->map.key         = key;
    f->map.bitmap_size = bitmap_size;
    f->src_addr        = src;
	f->num_funcs       = 0;
    f->next            = NULL;
	f->cm              = cam->cm;

    for(i = 0; i < bitmap_size; i++) {
        f->map.bitmap[i] = 0xff;
    }
    if((num_fragments) % 8) {
        f->map.bitmap[bitmap_size - 1] =
            (1 << (num_fragments % 8)) - 1;
    }
    print_bitmap(&f->map);

    //! backoff first!!!
    f->retx = 0;
    if(fst != NULL) {
        fetcher_state_t *tmp = fst;
		cam->status = FETCHING_QUEUED;

        while(tmp->next != NULL) { tmp = tmp->next; }
        tmp->next = f;
        return SOS_OK;
    }
	cam->status = FETCHING_STARTED;
    fst = f;
    //! setup timer
    ker_timer_start(KER_FETCHER_PID,
            FETCHER_REQUEST_TID,
            FETCHER_REQUEST_BACKOFF_SLOT * ((ker_rand() % FETCHER_REQUEST_MAX_SLOT) + 1));
    //DEBUG("request ret = %d\n", ret);
    return SOS_OK;
}
Exemple #7
0
static void print_bitmap(fetcher_bitmap_t *m)
{
	uint8_t i;
	int16_t delt = 0;
	char buf[DEBUG_BUFFER_SIZE];
	delt = sprintf(buf,"map: ");
	for(i = 0; i < m->bitmap_size; i++) {
		delt += sprintf(buf+delt,"0x%x ", m->bitmap[i]);
	}
	DEBUG_PID(KER_FETCHER_PID,"%s\n",buf);
}
Exemple #8
0
void pidCrtlCallback(struct lc *lc, struct lc_msg *msg)
{
	struct pidValues *pPid = (struct pidValues *)msg->data;
	switch (pPid->header.type) {
		case PID_RATE:
			DEBUG_PID("Set Rate:\n");
			SETKP(&pidRollRate, (float)pPid->KpR/100.0);
			SETKI(&pidRollRate, (float)pPid->KiR/100.0);
			SETKD(&pidRollRate, (float)pPid->KdR/100.0);
			SETKP(&pidPitchRate, (float)pPid->KpP/100.0);
			SETKI(&pidPitchRate, (float)pPid->KiP/100.0);
			SETKD(&pidPitchRate, (float)pPid->KdP/100.0);
			SETKP(&pidYawRate, (float)pPid->KpY/100.0);
			SETKI(&pidYawRate, (float)pPid->KiY/100.0);
			SETKD(&pidYawRate, (float)pPid->KdY/100.0);
			break;
		case PID_ATT:
			DEBUG_PID("Set ATT:\n");
			SETKP(&pidRoll, (float)pPid->KpR/100.0);
			SETKI(&pidRoll, (float)pPid->KiR/100.0);
			SETKD(&pidRoll, (float)pPid->KdR/100.0);
			SETKP(&pidPitch, (float)pPid->KpP/100.0);
			SETKI(&pidPitch, (float)pPid->KiP/100.0);
			SETKD(&pidPitch, (float)pPid->KdP/100.0);
			SETKP(&pidYaw, (float)pPid->KpY/100.0);
			SETKI(&pidYaw, (float)pPid->KiY/100.0);
			SETKD(&pidYaw, (float)pPid->KdY/100.0);
			break;
		default:
			DEBUG_PID("Error unkown type: %d", pPid->header.type);
			break;
	}

	commanderSetRPYType(
		(RPYType) IS_BIT_SET(pPid->header.mode, PID_ATT_MODE_R), 
		(RPYType) IS_BIT_SET(pPid->header.mode, PID_ATT_MODE_P), 
		(RPYType) IS_BIT_SET(pPid->header.mode, PID_ATT_MODE_Y)
	);
	lc_sendAct(lc);
}
Exemple #9
0
static inline void handle_overheard_fragment(Message *msg)
{
	fetcher_fragment_t *f;

	if ( send_state.map == NULL ) {
		return;
	}
	f = (fetcher_fragment_t*)msg->data;
	if( (send_state.map->key != f->key) ) {
		return;
	}	
	DEBUG_PID(KER_FETCHER_PID, "Surpress %d\n", (f->frag_id));
	send_state.map->bitmap[(f->frag_id) / 8] &= ~(1 << ((f->frag_id) % 8));
}
Exemple #10
0
static void send_fetcher_done()
{
	fetcher_cam_t *cam;
	DEBUG_PID(KER_FETCHER_PID,"Fetcher Done!\n");
	if( post_long(fst->requester, KER_FETCHER_PID, MSG_FETCHER_DONE, sizeof(fetcher_state_t), fst, SOS_MSG_RELEASE) != SOS_OK ) {

		no_mem_retry = true;
		ker_timer_start(KER_FETCHER_PID,
				FETCHER_REQUEST_TID,
				1024);
		return;
	}
	cam = ker_shm_get( KER_FETCHER_PID,  fst->map.key );
	cam->status = FETCHING_DONE;
	no_mem_retry = false;
	start_new_fetch();
}
Exemple #11
0
static void check_map_and_post()
{
	if(fst == NULL) {
		return;
	}
	if(check_map(&fst->map)) {
		fst->retx = 0;
#ifdef SOS_SIM
		/*
		 * We update module version here
		 */
		// TODO: figure out the right place...
		//set_version_to_sim(fst->map.mod_id, fst->map.version);
#endif
		DEBUG_PID(KER_FETCHER_PID, "Request Done!!!\n");
		ker_timer_stop(KER_FETCHER_PID, FETCHER_REQUEST_TID);
		send_fetcher_done();
	}
}
Exemple #12
0
static int8_t request_new_module(sos_cam_t key, loader_cam_t *cam, uint8_t size, uint16_t saddr, uint8_t type)
{
  cam->code_size = size; 
	cam->fetcher.fetchtype = type;
	cam->fetcher.cm = ker_codemem_alloc(
			size * LOADER_SIZE_MULTIPLIER, 
			CODEMEM_TYPE_EXECUTABLE);
	DEBUG_PID( KER_DFT_LOADER_PID, "request new module with size = %d\n", 
			size * LOADER_SIZE_MULTIPLIER);
	if(cam->fetcher.cm == CODEMEM_INVALID) {
		return -ENOMEM;
	}
	if( fetcher_request( KER_DFT_LOADER_PID, key, (uint16_t)size * LOADER_SIZE_MULTIPLIER, saddr ) 
			!= SOS_OK ) {
		ker_codemem_free( cam->fetcher.cm );
		return -ENOMEM;
	}
	block_protocol();
	return SOS_OK;

}
Exemple #13
0
static void start_experiment(uint16_t size)
{
	sos_cam_t key;
	loader_cam_t *cam;
	codemem_t cm;
	uint8_t buf[2];

	buf[0] = 128;
	buf[1] = 1;
	DEBUG_PID(KER_DFT_LOADER_PID, "start experiment: size = %d\n", size);
	cm = ker_codemem_alloc( size, CODEMEM_TYPE_EXECUTABLE);
	ker_codemem_write(cm, KER_DFT_LOADER_PID, buf, 2, 0);
	cam = ker_malloc(sizeof(loader_cam_t), KER_DFT_LOADER_PID);

	st.version_data->pam_ver[0]++;
	st.version_data->pam_size[0] = (size + (LOADER_SIZE_MULTIPLIER - 1)) / LOADER_SIZE_MULTIPLIER;
	st.version_data->version ++;

	key = ker_cam_key( KER_DFT_LOADER_PID, 0 );
	cam->fetcher.fetchtype = FETCHTYPE_DATA;
	cam->fetcher.cm = cm;
	ker_cam_add(key, cam);	
	restartInterval(0);
}
Exemple #14
0
static inline void send_fragment()
{
	uint16_t frag_id;
	uint8_t i, j;
	uint8_t mask = 1;
	uint8_t ret;
	fetcher_fragment_t *out_pkt;
	fetcher_cam_t *cam;

	if ( send_state.map == NULL ) {
		ker_timer_stop(KER_FETCHER_PID, FETCHER_TRANSMIT_TID);
		return;
	}

	cam = (fetcher_cam_t *) ker_shm_get( KER_FETCHER_PID, send_state.map->key);

	if ( cam == NULL ) {
		// file got deleted. give up!
		free_send_state_map();
		return;
	}

	if ( send_state.frag != NULL) {
		//! timer fires faster than data reading.  Highly unlikely...
		//! but we still handle it.
		return;
	}

	//! search map and find one fragment to send
	for(i = 0; i < send_state.map->bitmap_size; i++) {
		//! for each byte
		if(send_state.map->bitmap[i] != 0) {
			break;
		}
	}
	if(i == send_state.map->bitmap_size) {
		/*
		 * Did not find any block...
		 */
		free_send_state_map();
		return;
	}

	//sos_assert(i < send_state.map->bitmap_size);

	frag_id = i * 8;
	mask = 1;
	for(j = 0; j < 8; j++, mask = mask << 1) {
		if(mask & (send_state.map->bitmap[i])) {
			send_state.map->bitmap[i] &= ~(mask);
			break;
		}
	}
	//sos_assert(j < 8);
	frag_id += j;
	print_bitmap(send_state.map);
	out_pkt = (fetcher_fragment_t*)ker_malloc(sizeof(fetcher_fragment_t), KER_FETCHER_PID);
	if(out_pkt == NULL){
		DEBUG_PID(KER_FETCHER_PID,"malloc fetcher_fragment_t failed\n");
		goto send_fragment_postproc;
	}
	out_pkt->frag_id = ehtons(frag_id);
	out_pkt->key = ehtons(send_state.map->key);

	ret = ker_codemem_read(cam->cm, KER_FETCHER_PID,
			out_pkt->fragment, FETCHER_FRAGMENT_SIZE,
			frag_id * (code_addr_t)FETCHER_FRAGMENT_SIZE);
	if(ret == SOS_SPLIT) {
		send_state.frag = out_pkt;
	} else if(ret != SOS_OK){
		DEBUG_PID(KER_FETCHER_PID, "codemem_read failed\n");
		ker_free(out_pkt);
		goto send_fragment_postproc;
	}


	//DEBUG("out_pkt has addr %x\n", (int)out_pkt);
	DEBUG_PID(KER_FETCHER_PID, "send_fragment: frag_id = %d to %d\n", frag_id, send_state.dest);
	ret = post_auto(KER_FETCHER_PID,
			KER_FETCHER_PID,
			MSG_FETCHER_FRAGMENT,
			sizeof(fetcher_fragment_t),
			out_pkt,
			SOS_MSG_RELEASE | SOS_MSG_RELIABLE,
			send_state.dest);
	if( ret == SOS_OK ) {
		send_state.num_msg_in_queue++;	
	}
send_fragment_postproc:
	if(check_map(send_state.map)) {
		//! no more fragment to send
		free_send_state_map();
	}
}
Exemple #15
0
static int8_t fetcher_handler(void *state, Message *msg)
{
    switch (msg->type) {
        case MSG_FETCHER_FRAGMENT:
        {
			fetcher_fragment_t *f;
			f = (fetcher_fragment_t*)msg->data;
			f->key = entohs( f->key );
			f->frag_id = entohs(f->frag_id);

			DEBUG_PID(KER_FETCHER_PID,"MSG_FETCHER_FRAGMENT:\n");
			handle_overheard_fragment(msg);
			if(fst == NULL) {
				DEBUG_PID(KER_FETCHER_PID, "NO Request!!!\n");
				return SOS_OK;  //!< no request
			}
			//DEBUG_PID(KER_FETCHER_PID,"calling restart_request_timer()\n");
			restart_request_timer();
			fst->retx = 0;
			//DEBUG_PID(KER_FETCHER_PID,"calling handle_data()\n");
			return handle_data(msg);
		}
		case MSG_FETCHER_REQUEST:
		{
			fetcher_bitmap_t *bmap =
				(fetcher_bitmap_t *) msg->data;
			bmap->key = entohs( bmap->key );

			//! received request from neighbors
			DEBUG("handling request to %d from %d\n", msg->daddr, msg->saddr);
			if(msg->daddr == ker_id()) {
				return handle_request(msg);
			}
			if(fst == NULL) return SOS_OK;  //!< no request
			restart_request_timer();
			fst->retx = 0;
			return SOS_OK;
		}
		case MSG_TIMER_TIMEOUT:
		{
			MsgParam *params = (MsgParam*)(msg->data);
			if(params->byte == FETCHER_REQUEST_TID) {
				//DEBUG("request timeout\n");
				if( no_mem_retry ) {
					send_fetcher_done();
					return SOS_OK;
				}
				handle_request_timeout();
			} else if(params->byte == FETCHER_TRANSMIT_TID) {
				//DEBUG("send fragment timeout\n");
				if( send_state.num_msg_in_queue < FETCHER_MAX_MSG_IN_QUEUE ) {
					send_fragment();
				}
			}
			return SOS_OK;
		}
		case MSG_PKT_SENDDONE:
		{
			if( send_state.num_msg_in_queue > 0 ) {
				send_state.num_msg_in_queue--;
			}
			return SOS_OK;
		}
#ifdef SOS_HAS_EXFLASH
		case MSG_EXFLASH_WRITEDONE:
		{
			ker_free(send_state.fragr);
			send_state.fragr = NULL;
			check_map_and_post();
			return SOS_OK;
		}
		case MSG_EXFLASH_READDONE:
		{

			post_auto(KER_FETCHER_PID,
					KER_FETCHER_PID,
					MSG_FETCHER_FRAGMENT,
					sizeof(fetcher_fragment_t),
					send_state.frag,
					SOS_MSG_RELEASE,
					send_state.dest);
			send_state.frag = NULL;
			return SOS_OK;
		}
#endif
		case MSG_INIT:
		{
			send_state.map = NULL;
			send_state.frag = NULL;
			send_state.fragr = NULL;
			send_state.num_msg_in_queue = 0;	
			ker_msg_change_rules(KER_FETCHER_PID, SOS_MSG_RULES_PROMISCUOUS);
			ker_permanent_timer_init(&(send_state.timer), KER_FETCHER_PID, FETCHER_TRANSMIT_TID, TIMER_REPEAT);
			ker_timer_init(KER_FETCHER_PID, FETCHER_REQUEST_TID, TIMER_ONE_SHOT);
			return SOS_OK;
		}

	}
	return -EINVAL;
}
Exemple #16
0
static int8_t handle_fetcher_done( Message *msg ) 
{
	fetcher_state_t *f = (fetcher_state_t*) msg->data;
	if( is_fetcher_succeed( f ) == true ) {
		//mod_header_ptr p;
		loader_cam_t *cam;
		fetcher_commit(f, true);

		st.blocked = 0;
		restartInterval( 0 );

		cam = ker_cam_lookup( f->map.key );
		if( cam->fetcher.fetchtype == FETCHTYPE_DATA) {
			uint8_t buf[2];
			ker_codemem_read( cam->fetcher.cm, KER_DFT_LOADER_PID, buf, 2, 0);
			post_short(buf[0], KER_DFT_LOADER_PID, MSG_LOADER_DATA_AVAILABLE,
					buf[1], cam->fetcher.cm, 0);
			DEBUG_PID(KER_DFT_LOADER_PID, "Data Ready\n" );
#ifdef LOADER_NET_EXPERIMENT
			ker_led(LED_GREEN_TOGGLE);
#endif
		} else {
		  uint8_t mcu_type;
#ifndef SOS_SIM
		  uint8_t plat_type;
#endif
		  mod_header_ptr p;
#ifdef MINIELF_LOADER
		  // Link and load the module here
		  melf_load_module(cam->fetcher.cm);
#endif//MINIELF_LOADER		  
		  // Get the address of the module header
		  p = ker_codemem_get_header_address( cam->fetcher.cm ); 

		  // get processor type and platform type
		  mcu_type = sos_read_header_byte(p, 
										  offsetof( mod_header_t, processor_type )); 
#ifdef SOS_SIM
		  if( (mcu_type == MCU_TYPE) )
			// In simulation, we don't check for platform
#else
			plat_type = sos_read_header_byte(p, 
											 offsetof( mod_header_t, platform_type )); 
		  if( (mcu_type == MCU_TYPE) && 
			  ( plat_type == HW_TYPE || plat_type == PLATFORM_ANY) )
#endif
			{
			  
			  /*
			   * If MCU is matched, this means we are using the same 
			   * instruction set.
			   * And if this module is for this *specific* platform or 
			   * simply for all platform with the same MCU
			   */
			  // mark module executable
			  ker_codemem_mark_executable( cam->fetcher.cm );
			  if (cam->version & 0x80) {
#ifdef SOS_SFI
#ifdef MINIELF_LOADER
				sfi_modtable_register(cam->fetcher.cm);
				if (SOS_OK == ker_verify_module(cam->fetcher.cm)){
				  sfi_modtable_flash(p);
				  ker_register_module(p);
				}
				else
				  sfi_exception(KER_VERIFY_FAIL_EXCEPTION);
#else				
				uint16_t init_offset, code_size, handler_addr;
				uint32_t handler_byte_addr, module_start_byte_addr;
				uint16_t handler_sfi_addr;
				handler_sfi_addr = sos_read_header_ptr(p, offsetof(mod_header_t, module_handler));
				handler_addr = sfi_modtable_get_real_addr(handler_sfi_addr);				
				handler_byte_addr = (handler_addr * 2);
				module_start_byte_addr = (p * 2);
				init_offset = (uint16_t)(handler_byte_addr - module_start_byte_addr);
				code_size = cam->code_size * LOADER_SIZE_MULTIPLIER;
				if (SOS_OK == ker_verify_module(cam->fetcher.cm, init_offset, code_size)){
				  sfi_modtable_flash(p);				  
				  ker_register_module(p);
				}
				else
				  sfi_exception(KER_VERIFY_FAIL_EXCEPTION);
#endif //MINIELF_LOADER
#else
				ker_register_module(p);
#endif //SOS_SFI
			  }
			}

		}
		process_version_data( st.version_data, st.recent_neighbor);
	} else {
	  DEBUG_PID( KER_DFT_LOADER_PID, "Fetch failed!, request %d\n", st.recent_neighbor);
	  f = (fetcher_state_t*) ker_msg_take_data(KER_DFT_LOADER_PID, msg);
	  fetcher_restart( f, st.recent_neighbor );
	}
	return SOS_OK;
}