⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 chatmain.c

📁 基于cc1010的设计实例
💻 C
📖 第 1 页 / 共 2 页
字号:
			// Join request
			while ((temp = sendJoinRequest()) != JOIN_ACCEPTED) {
				if (temp == JOIN_DENIED) {
					printf("\nInvalid nick name / The server is full!");
					while (TRUE);
				} else {
					printf("\nJoin error (RF related)");
					halWait(255, CLK_FREQ);
					printf(" -> retrying now...");
					halWait(255, CLK_FREQ);
				}
			}
			sppSettings.myAddress = pMyCI->address;

			// Initialize the ping timeout (we'll reset the countdown each 
			// time we receive a ping or some other message from the server
			noPingTicks = NO_PING_TIMEOUT;
			sppSetTimerCB(SPP_CUSTOM_0_TIMER, disconnected, &noPingTicks);

			break;
		}
	}

	// Initialize the chat screen
	VT100_INIT_CHAT_SCREEN();

    // Setup UART0 for interrupt driven I/O 
    UART0_SETUP(38400, CLK_FREQ, UART_NO_PARITY | UART_RX_TX | UART_ISR);
	INT_SETFLAG(INUM_UART0_TX, INT_SET);

	// Initialize some chat variables
	inPos = 0;
	TXI.status = SPP_TX_FINISHED;
	txRequest = TX_REQUEST_OFF;
	noDecryption = FALSE;
	isPrivateMode = FALSE;

	printClientList();

	// Loop forever
	while (TRUE) {

		// Turn on reception
		RXI.maxDataLen = BUFFER_LENGTH;
		RXI.pDataBuffer = pRXBuffer;
		sppReceive(&RXI);

		// Wait for RF RX to complete
		do {
			if (txRequest && (TXI.status == SPP_TX_FINISHED) && (RXI.status == SPP_RX_WAITING)) {
				sppReset();
			}
		} while (SPP_STATUS() != SPP_IDLE_MODE); 

		// Process incoming messages, if any
		if (RXI.status == SPP_RX_FINISHED) {
			YLED = LED_ON;
			processMessage();
			YLED = LED_OFF;
		}

		// Server transmits ping
		if (!txRequest && (pMyCI->address == SERVER_ADDRESS)) {
			YLED = LED_ON;

			// Prepare the transmission settings
			TXI.destination = SPP_BROADCAST;
			TXI.dataLen = 2;
			TXI.pDataBuffer = pAdminTXBuffer;
			TXI.flags = MSG_PING;

			// Reset the 16-bit array
			pAdminTXBuffer[0] = 0x00;
			pAdminTXBuffer[1] = 0x00;

			// pAdminTXBuffer[0]  pAdminTXBuffer[1]
			// MSB(15) ... LSB(8) MSB(7) ... LSB(0)
			for (n = 1; n < 16; n++) {
				if (CI[n].address == INVALID_ADDRESS) {
					// Do nothing
				} else if (CI[n].address < 8) {
					pAdminTXBuffer[1] |= (0x01 << CI[n].address);
				} else { // CI[n].address >= 8
					pAdminTXBuffer[0] |= (0x01 << (CI[n].address - 8));
				}
			}

			// Send it
			sppSend(&TXI);
			while (SPP_STATUS() != SPP_IDLE_MODE);
			YLED = LED_OFF;
		}

		// Transmit outgoing messages 
		if (txRequest) {
			YLED = LED_ON;

			// PRIVATE MESSAGE
			if (isPrivateMode) {

				// Make sure that the DES key is valid
				pCI = getClientInfo(privateAddress);
				if (!pCI->isDESKeyValid) {
					
					// Discard the message if the key exchange fails.
					if (!diffieHellmanUp(privateAddress)) {
						printStatus(KEY_EXCHANGE_FAILED, privateAddress);
						clearInputSection();
						isPrivateMode = FALSE;
						inPos = 0;
						txRequest = TX_REQUEST_OFF;
						UART0_FLOW_CONTROL = READY;
					} else {
						printStatus(KEY_EXCHANGE_OK, privateAddress);
					}						
				}

				if (pCI->isDESKeyValid && getClientInfo(privateAddress)) {

					// Prepare the transmission settings
					TXI.destination = privateAddress;
					TXI.flags = (pCI->txFlags & SPP_SEQUENCE_BIT) | SPP_ACK_REQ | SPP_ENCRYPTED_DATA | MSG_CHAT_DOWN;
					TXI.dataLen = inPos;
					TXI.pDataBuffer = pMessageTXBuffer;

					// Encrypt the text with single DES
					halDES(DES_SINGLE_DES | DES_ENCRYPT | DES_OFB_MODE, TXI.pDataBuffer, pCI->pDESKey, TXI.dataLen);

					// Send it
					sppSend(&TXI);
					while (SPP_STATUS() != SPP_IDLE_MODE);

					// If OK, print the message, clear the input line, and get ready for more input
					if (TXI.status == SPP_TX_FINISHED) {
						pCI->txFlags = TXI.flags;
						sppSettings.rxTimeout = LONG_RX_TIMEOUT;

						// We'll have to decrypt the message to be able to print it
						halDES(DES_SINGLE_DES | DES_DECRYPT | DES_OFB_MODE, TXI.pDataBuffer, pCI->pDESKey, TXI.dataLen);
						printMessage(pMyCI->name, isPrivateMode, pMessageTXBuffer, TXI.dataLen);
						clearInputSection();
						isPrivateMode = FALSE;
						inPos = 0;
						txRequest = TX_REQUEST_OFF;
						UART0_FLOW_CONTROL = READY;
						RLED = LED_OFF;
					} else {
						sppSettings.rxTimeout = RETRY_TX_TIMEOUT;
						RLED = LED_ON;
					}
				}

			// SERVER BROADCAST
			} else if (pMyCI->address == SERVER_ADDRESS) {

				// Send the message to all clients
				broadcastMessage(SERVER_ADDRESS, pMessageTXBuffer, inPos);

				// Print the message, clear the input line, and get ready for more input
				printMessage(pMyCI->name, isPrivateMode, pMessageTXBuffer, inPos);
				clearInputSection();
				inPos = 0;
				txRequest = TX_REQUEST_OFF;
				UART0_FLOW_CONTROL = READY;

			// CLIENT BROADCAST (VIA SERVER)
			} else {
				// Prepare the transmission settings
				TXI.destination = SERVER_ADDRESS;
				TXI.flags = (getClientInfo(SERVER_ADDRESS)->txFlags & SPP_SEQUENCE_BIT) | SPP_ACK_REQ | MSG_CHAT_UP;
				TXI.dataLen = inPos;
				TXI.pDataBuffer = pMessageTXBuffer;

				// Send the message to the server
				sppSend(&TXI);
				while (SPP_STATUS() != SPP_IDLE_MODE);

				// If OK, print the message, clear the input line, and get ready for more input
				if (TXI.status == SPP_TX_FINISHED) {
					getClientInfo(SERVER_ADDRESS)->txFlags = TXI.flags;
					sppSettings.rxTimeout = LONG_RX_TIMEOUT;
					printMessage(pMyCI->name, isPrivateMode, pMessageTXBuffer, inPos);
					clearInputSection();
					inPos = 0;
					txRequest = TX_REQUEST_OFF;
					UART0_FLOW_CONTROL = READY;
					RLED = LED_OFF;
				} else {
					sppSettings.rxTimeout = RETRY_TX_TIMEOUT;
					RLED = LED_ON;
				}
			}
			YLED = LED_OFF;
		}
	}
} // main




//----------------------------------------------------------------------------
//  UART0 0 interrupt service routine: Message input
//----------------------------------------------------------------------------
void UART0_ISR () interrupt INUM_UART0 {
	char typedChar;

	// Ignore TX interrupts
	if (TI_0) {
		INT_SETFLAG(INUM_UART0_TX, INT_CLR);
		return;
	}	

	if (RI_0) {
		INT_SETFLAG(INUM_UART0_RX, INT_CLR);

		// ENTER transmits the message (if there is any)
		if ((typedChar = UART0_RECEIVE()) == TERMINAL_KEY_ENTER) {
			if (inPos > 0) {
				// Send the message
				UART0_FLOW_CONTROL = STOP;
				txRequest = TX_REQUEST_ON;
			}

		// Max input length exceeded, or ENTER has already been hit
		} else if ((inPos >= MAX_INPUT_LENGTH) || txRequest) {
			// Do nothing :)

		// BACKSPACE deletes the last character (go back, print space, go back again)
		} else if (typedChar == TERMINAL_KEY_BACKSPACE) {
			if (inPos > 0) {
				INT_SETFLAG(INUM_UART0_TX, INT_SET);
				VT100_GO_TO_POS(20, inPos);
				putchar(' ');
				VT100_GO_TO_POS(20, inPos);
				inPos--;
			}

		// NORMAL (printable) characters 
		} else if (isprint(typedChar)) {
			INT_SETFLAG(INUM_UART0_TX, INT_SET);

			// Put the character into the TX buffer
			pMessageTXBuffer[inPos++] = typedChar;

			// Private mode check (Input begins with "##<")
			if (inPos == 3) {
				if (pMessageTXBuffer[2] == '<') {
					if (isxdigit(pMessageTXBuffer[0]) && isxdigit(pMessageTXBuffer[1])) {
						privateAddress = strtoul(pMessageTXBuffer, NULL, 16);
						if ((getClientInfo(privateAddress) != NULL) && (privateAddress != pMyCI->address)) {
							isPrivateMode = TRUE;
						} else {
							isPrivateMode = FALSE;
						}
					} else {
						isPrivateMode = FALSE;
					}
				} else {
					isPrivateMode = FALSE;
				}
			}

			// Make it possible to turn off/on the message decryption
			if ((inPos == 1) && (pMessageTXBuffer[0] == '<')) {
				noDecryption = ~noDecryption;
				inPos = 0;
				printStatus(DECRYPTION_MODE, NULL);
				clearInputSection();

			} else {
				// Local echo
				VT100_GO_TO_POS(20, inPos);
				putchar(typedChar);
			}
		}

		// Turn off the UART TX interrupt flag (it will be high because of the putchar() calls)
		INT_SETFLAG(INUM_UART0_TX, INT_CLR);
	}
} // UART0_ISR




//----------------------------------------------------------------------------
//  void disconnected (void)
//
//  Description:
//      This function is used by clients when the communication with the 
//		server has broken down.
//----------------------------------------------------------------------------
void disconnected (void) {
	printStatus(DISCONNECTED, NULL);
	while (TRUE);
} // disconnected

⌨️ 快捷键说明

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