deluge_app.c

来自「MANTIS是由科罗拉多大学开发的传感器网络嵌入式操作系统。 这是mantis」· C语言 代码 · 共 1,317 行 · 第 1/3 页

C
1,317
字号
		{			if ((txpackets[txidx] & txmask)!=0)			{				mos_mutex_lock(&app->delugeLock);				mos_file_read(spkt.data, app->image_file, txaddr, DELUGE_PACKET_SIZE);				mos_mutex_unlock(&app->delugeLock);											foot->packet = i;				spkt.size = DELUGE_PACKET_SIZE+sizeof(deluge_foot_data);	// com_send may have changed it											// Last two bytes of last packet have page CRC				if (i == DELUGE_PACKETS_PER_PAGE-1) {					*(uint16_t*)&(spkt.data[DELUGE_PACKET_SIZE-2]) = crc;				}											net_send(&spkt, DELUGE_PROTO_ID, deluge_portmap[app->index], deluge_portmap[app->index]);							ih = mos_disable_ints();				app->outgoingPackets[txidx] &= ~txmask;				txpackets[txidx] = app->outgoingPackets[txidx];				mos_enable_ints(ih);								mos_thread_sleep(app->txDelay);			}						txaddr = txaddr + DELUGE_PACKET_SIZE;			txmask = txmask << 1;			if (txmask == 0) {				txmask = 1;				txidx++;			}		}						ih = mos_disable_ints();		txpackets[0] = app->outgoingPackets[0];		txpackets[1] = app->outgoingPackets[1];		txpackets[2] = app->outgoingPackets[2];		mos_enable_ints(ih);	}	// Rule T.2	//app->state = DELUGE_STATE_MAINTAIN;	//mos_sem_post(&timeout_sem);	//deluge_wakeup(&table[app->index]);	stateTransition(app, DELUGE_STATE_MAINTAIN);}/* FORWARD state is a combination of RX and TX states.  The node will fill as * many requests as it can from its cache, and forward requests it can't handle * to its parent.  The node's state will return to MAINTAIN once the request * is fully filled or too many requests time out.  To minimize contention, data * is only forwarded when the page is completed or the request times out or a * new request is received. */static void doForward(deluge_app* app){	// TX	deluge_foot_data* foot = (deluge_foot_data*)&spkt.data[DELUGE_PACKET_SIZE];	mos_mutex_lock(&app->delugeLock);	foot->version = app->dcb.version;	#if DELUGE_CACHE_PAGES > 1	int8_t page = app->outgoingCachePage;	#else	int8_t page = 0;	#endif	foot->page = app->outgoingPage;	foot->id = mos_node_id_get();	foot->type = DELUGE_PACKET_DATA;	// Packets that have been requested of us	uint16_t txpackets[3] = { app->outgoingPackets[0], app->outgoingPackets[1], app->outgoingPackets[2] };	// Packets we have cached	uint16_t capackets[3] = { app->cachedPackets[0], app->cachedPackets[1], app->cachedPackets[2] };	mos_mutex_unlock(&app->delugeLock);	app->nPacketsRequested = 0;	// Loop as long as we have packets to fill the request	while (app->state == DELUGE_STATE_FORWARD &&		((txpackets[0]&capackets[0]) != 0 || (txpackets[1]&capackets[1]) != 0 || (txpackets[2]&capackets[2]) != 0))	{		uint8_t i, ih;		uint16_t txmask = 1;		uint8_t txidx = 0;		uint32_t txaddr = DELUGE_ADDR(page, 0);		for (i=0; i<DELUGE_PACKETS_PER_PAGE; i++)		{			if ((txpackets[txidx] & capackets[txidx] & txmask)!=0)			{				mos_mutex_lock(&app->delugeLock);				mos_file_read(spkt.data, app->image_file, txaddr, DELUGE_PACKET_SIZE);				mos_mutex_unlock(&app->delugeLock);											foot->packet = i;				spkt.size = DELUGE_PACKET_SIZE+sizeof(deluge_foot_data);	// net_send may have changed it											// Last two bytes of last packet have page CRC				// We don't compute it ourselves, since we might not have				// the entire page cached				if (i == DELUGE_PACKETS_PER_PAGE-1) {					*(uint16_t*)&(spkt.data[DELUGE_PACKET_SIZE-2]) = app->incomingcrc;				}											net_send(&spkt, DELUGE_PROTO_ID, deluge_portmap[app->index], deluge_portmap[app->index]);							ih = mos_disable_ints();				app->outgoingPackets[txidx] &= ~txmask;				txpackets[txidx] = app->outgoingPackets[txidx];				mos_enable_ints(ih);								mos_thread_sleep(app->txDelay);			} else if ((txpackets[txidx] & txmask) != 0) {				app->nPacketsRequested++;			}						txaddr = txaddr + DELUGE_PACKET_SIZE;			txmask = txmask << 1;			if (txmask == 0) {				txmask = 1;				txidx++;			}		}						ih = mos_disable_ints();		txpackets[0] = app->outgoingPackets[0];		txpackets[1] = app->outgoingPackets[1];		txpackets[2] = app->outgoingPackets[2];		capackets[0] = app->cachedPackets[0];		capackets[1] = app->cachedPackets[1];		capackets[2] = app->cachedPackets[2];				// As long as we are filling requests, don't let incoming requests		// inflate our total timeout count		if (app->nRequests) app->nRequests--;		mos_enable_ints(ih);	}		if (txpackets[0]==0 && txpackets[1]==0 && txpackets[2]==0) {		// We are done		app->nRequests = 0;		//app->state = DELUGE_STATE_MAINTAIN;		//deluge_wakeup(&table[app->index]);		stateTransition(app, DELUGE_STATE_MAINTAIN);		return;	}	// RX	if (app->nRequests < DELUGE_LAMBDA) {		// Rule R.1		deluge_foot_request* request = (deluge_foot_request*)spkt.data;		mos_mutex_lock(&app->delugeLock);		request->to = app->updaterNode;		// Request the packets that were requested of us		request->packets[0] = (app->incomingPackets[0] |= app->outgoingPackets[0]);		request->packets[1] = (app->incomingPackets[1] |= app->outgoingPackets[1]);		request->packets[2] = (app->incomingPackets[2] |= app->outgoingPackets[2]);		request->version = app->dcb.version;		request->page = app->dcb.incomingPage;		mos_mutex_unlock(&app->delugeLock);		request->rateChange = app->nRequests-1;		request->id = mos_node_id_get();		request->type = DELUGE_PACKET_REQUEST;		spkt.size = sizeof(deluge_foot_request);							net_send(&spkt, DELUGE_PROTO_ID, deluge_portmap[app->index], deluge_portmap[app->index]);		app->nRequests++;	} else {		// TODO: check reception rate		app->nRequests = 0;		// Assume parent node is dead; assign the highest possible DTB; 		// we'll take any node with a lower DTB		app->dtb = 0xFF;		/*#ifdef DELUGE_LINK_QUALITY		app->dtb_votes[app->updater_index] = 0;		#endif*/		#ifdef DELUGE_SYMMETRIC_LINKS		clearSymmetry(app, app->updaterNode);		/*if (nextSymmetric(app) != 255) {			app->nRequests = 0;			stateTransition(app, DELUGE_STATE_FORWARD);			return;		}*/		#endif		#ifdef DELUGE_CLEAR_OUTGOING		app->outgoingPackets[0] = 0;		app->outgoingPackets[1] = 1;		app->outgoingPackets[2] = 2;		#endif		stateTransition(app, DELUGE_STATE_MAINTAIN);		return;	}	// wait a while before requesting again	setRequestTimeout(app, DELUGE_STATE_FORWARD);}void deluge_dispatch(deluge_app* app){	/*if (app->wakeup_reason == PACKET_RECEIVED)		clearTimeout(app);*/	switch (app->state)	{		case DELUGE_STATE_MAINTAIN:			doMaintain1(app);			break;		case DELUGE_STATE_MAINTAIN2:			doMaintain2(app);			break;		case DELUGE_STATE_RX:			doRx(app);			break;		case DELUGE_STATE_TX:			doTx(app);			break;		case DELUGE_STATE_FORWARD:			doForward(app);			break;	}}void handleSummary(deluge_app* app, deluge_foot_summary* summary){	mos_mutex_lock(&app->delugeLock);	checkNeighbor(app, summary->id);	mos_mutex_unlock(&app->delugeLock);		switch (app->state)	{		case DELUGE_STATE_MAINTAIN:		case DELUGE_STATE_MAINTAIN2: {			mos_mutex_lock(&app->delugeLock);			// Nodes that are far away from the base should not suppress us			//if (summary->dtb < app->dtb)				app->nSummaries++;			if (				#ifndef DELUGE_NO_FORWARD				app->index == 0 &&				#endif				#ifdef DELUGE_SYMMETRIC_LINKS				checkSymmetry(app, summary) &&				#endif				summary->version == app->dcb.version &&				summary->highPage > app->dcb.highPage				#ifndef DELUGE_NO_FORWARD				#ifndef MEMBER_NO_DTB				&& summary->dtb < app->dtb				#else				&& summary->dtb < 255				#endif				#endif				)			{				// We ignore summaries from a node that is farther from the root				// than our last parent.  If this parent ever fails to update				// us, we set the DTB to the maximum, in which case we no longer				// ignore summaries.				app->updaterNode = summary->id;				// DTB ensures that we get our updates from the closest source				app->dtb = summary->dtb + 1;				// Rule M.5				if (!app->heardRequest && !app->heardData) {					app->nRequests = 0;					stateTransition(app, DELUGE_STATE_RX);				}				app->detectedInconsistency = 1;			}			#ifndef DELUGE_NO_FORWARD			else if (app->index != 0 &&				#ifdef DELUGE_SYMMETRIC_LINKS				checkSymmetry(app, summary) &&				#endif				summary->version == app->dcb.version &&				(summary->highPage > app->dcb.highPage ||				(summary->highPage == app->dcb.highPage &&				/*#ifdef DELUGE_LINK_QUALITY				checkDtb(app, summary->id, summary->dtb)				#else*/				summary->dtb < app->dtb				//#endif				)))			{				// We will send this page index in our own summaries				app->dcb.highPage = summary->highPage;				// DTB ensures that we get our updates from the closest source				// and prevents routing loops from forming				app->dtb = summary->dtb + 1;				app->detectedInconsistency = 1;				// Take note of our new parent, but don't switch to RX state				app->updaterNode = summary->id;				// If we have a previously pending request, switch back to				// FORWARD state				// Rule M.5				if (!app->heardRequest && !app->heardData &&					((app->incomingPackets[0]&app->outgoingPackets[0]) ||					(app->incomingPackets[1]&app->outgoingPackets[1]) ||					(app->incomingPackets[2]&app->outgoingPackets[2])))				{					app->nRequests = 0;					stateTransition(app, DELUGE_STATE_FORWARD);				}			}			#endif			else if (summary->version != app->dcb.version ||				summary->highPage != app->dcb.highPage ||				(summary->highPage == app->dcb.highPage &&				summary->dtb > app->dtb+1))			{				app->detectedInconsistency = 1;				if (summary->version < app->dcb.version)					app->heardObsolete = 1;				stateTransition(app, DELUGE_STATE_MAINTAIN);			}			mos_mutex_unlock(&app->delugeLock);		} break;		case DELUGE_STATE_RX: break;		case DELUGE_STATE_TX: break;		case DELUGE_STATE_FORWARD: break;	}}void handleProfile(deluge_app* app, deluge_foot_profile* profile){	mos_mutex_lock(&app->delugeLock);	checkNeighbor(app, profile->id);	mos_mutex_unlock(&app->delugeLock);		switch (app->state)	{		case DELUGE_STATE_MAINTAIN:		case DELUGE_STATE_MAINTAIN2: {			mos_mutex_lock(&app->delugeLock);			app->nProfiles++;			if (profile->version > app->dcb.version)			{				#ifdef DELUGE_PRINT_EVENT				printf_P(sNewVer);				printf_P(sDisplayTime);		// display time				#endif				aqshell_send(AQSHELL_NEWVERSION, &profile->version, 1);								app->dcb.codeSize = profile->codeSize;				app->dcb.version = profile->version;				app->dcb.incomingPage = 0;				app->dcb.highPage = 0;				app->dcb.goalPage = profile->goalPage;				app->dcb.programcrc = profile->crc;				app->outgoingPackets[0] = 0;				app->outgoingPackets[1] = 0;				app->outgoingPackets[2] = 0;				app->dtb = 0xFF;								uint8_t i;				for (i=0; i<sizeof(app->dcb.pagesNeeded); i++)					app->dcb.pagesNeeded[i] = 0xFF;				// Find the next page after the last program image we wrote				if (app->index == 0) {					app->image_file = mos_file_create("prg", app->dcb.codeSize);					app->incomingPackets[0] = -1;					app->incomingPackets[1] = -1;					app->incomingPackets[2] = -1;					app->nPacketsRequested = DELUGE_PACKETS_PER_PAGE;				} else {					char name[4] = { 'a', 'q', '0'+app->index, 0 };					#ifdef DELUGE_NO_FORWARD					app->image_file = mos_file_create(name, app->dcb.codeSize);					app->incomingPackets[0] = -1;					app->incomingPackets[1] = -1;					app->incomingPackets[2] = -1;					app->nPacketsRequested = DELUGE_PACKETS_PER_PAGE;					#else					app->image_file = mos_file_create(name, 						(uint32_t)DELUGE_PAGE_SIZE*(uint32_t)DELUGE_CACHE_PAGES);					app->incomingPackets[0] = 0;					app->incomingPackets[1] = 0;					app->incomingPackets[2] = 0;					app->nPacketsRequested = 0;					#endif					#if DELUGE_CACHE_PAGES > 1					int8_t i;					for (i=0; i<DELUGE_CACHE_PAGES; i++)						app->cache_map[i] = -1;					app->outgoingCachePage = 0;					app->incomingCachePage = 0;					#endif					app->cachedPackets[0] = 0;					app->cachedPackets[1] = 0;					app->cachedPackets[2] = 0;				}				deluge_saveState(app);			}			mos_mutex_unlock(&app->delugeLock);		} break;		case DELUGE_STATE_RX: break;		case DELUGE_STATE_TX: break;		case DELUGE_STATE_FORWARD: break;	}}void handleRequest(deluge_app* app, deluge_foot_request* request){	mos_mutex_lock(&app->delugeLock);	checkNeighbor(app, request->id);	mos_mutex_unlock(&app->delugeLock);		switch (app->state)	{		case DELUGE_STATE_MAINTAIN:		case DELUGE_STATE_MAINTAIN2: {			mos_mutex_lock(&app->delugeLock);			app->detectedInconsistency = 1;			if (request->version == app->dcb.version &&				request->page < app->dcb.highPage)			{				if (request->to == mos_node_id_get())				{					// Rule M.6					app->outgoingPage = request->page;					uint8_t ih = mos_disable_ints();					app->outgoingPackets[0] = request->packets[0];					app->outgoingPackets[1] = request->packets[1];					app->outgoingPackets[2] = request->packets[2];					mos_enable_ints(ih);										app->txDelay += request->rateChange * DELUGE_TX_DELAY_INC;					if (app->txDelay < DELUGE_TX_DELAY_MIN) 						app->txDelay = DELUGE_TX_DELAY_MIN;					else if (app->txDelay > DELUGE_TX_DELAY_MAX)						app->txDelay = DELUGE_TX_DELAY_MAX;										#ifdef DELUGE_NO_FORWARD					stateTransition(app, DELUGE_STATE_TX);					#else					if (app->index == 0) {			 			stateTransition(app, DELUGE_STATE_TX);					} else if (app->dtb != 255) {						#if DELUGE_CACHE_PAGES > 1						// Is the page in the cache?						int8_t page = cachedPageIndex(app, request->page);						if (page >= 0) {	// Yes

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?