예제 #1
0
static inline int8_t set_num_funcs_in_send_state(sos_shm_t key)
{
	fetcher_cam_t *cam;
	mod_header_t hdr;
	cam = (fetcher_cam_t *) ker_shm_get( KER_FETCHER_PID, key);

	if( cam == NULL ) {
		// We don't have the module, give up
		return -EINVAL;
	}

	if( cam->fetchtype != FETCHTYPE_MODULE ) {
		// not module
		return SOS_OK;
	}
	// if we are currently fetching the same module
	if( fst != NULL && (fst->map.key == key) ) {
		if( (fst->map.bitmap[0] & 0x01) != 0 ) {
			// number func is not available
			return -EINVAL;
		}
	}
	// read module header from flash and set it
	if( ker_codemem_read(cam->cm, KER_FETCHER_PID, 
				&hdr, sizeof(mod_header_t), 0) != SOS_OK ) {
		return -EINVAL;
	}
	send_state.num_funcs = hdr.num_sub_func + hdr.num_prov_func;
	return SOS_OK;
}
예제 #2
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;
}
예제 #3
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();
	}
}
예제 #4
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;
}