/********************************************************************* * Function: BOOL UDPPut(BYTE v) * * PreCondition: UDPIsPutReady() == TRUE with desired UDP socket * that is to be loaded. * * Input: v - Data byte to loaded into transmit buffer * * Output: TRUE if transmit buffer is still ready to accept * more data bytes * * FALSE if transmit buffer can no longer accept * any more data byte. * * Side Effects: None * * Overview: Given data byte is put into UDP transmit buffer * and active UDP socket buffer length is incremented * by one. * If buffer has become full, FALSE is returned. * Or else TRUE is returned. * * Note: This function loads data into an active UDP socket * as determined by previous call to UDPIsPutReady() ********************************************************************/ BOOL UDPPut(BYTE v) { UDP_SOCKET_INFO *p; WORD temp; p = &UDPSocketInfo[activeUDPSocket]; if ( p->TxCount == 0 ) { /* * This is the very first byte that is loaded in UDP buffer. * Remember what transmit buffer we are loading, and * start loading this and next bytes in data area of UDP * packet. */ p->TxBuffer = MACGetTxBuffer(); IPSetTxBuffer(p->TxBuffer, sizeof(UDP_HEADER)); p->TxOffset = 0; } /* * Load it. */ MACPut(v); if ( p->TxOffset++ >= p->TxCount ) p->TxCount++; #if 0 /* * Keep track of number of bytes loaded. * If total bytes fill up buffer, transmit it. */ p->TxCount++; #endif #define SIZEOF_MAC_HEADER (14) /* * Depending on what communication media is used, allowable UDP * data length will vary. */ #if !defined(STACK_USE_SLIP) #define MAX_UDP_DATA (MAC_TX_BUFFER_SIZE - SIZEOF_MAC_HEADER - sizeof(IP_HEADER) - sizeof(UDP_HEADER)) #else #define MAX_UDP_DATA (MAC_TX_BUFFER_SIZE - sizeof(IP_HEADER) - sizeof(UDP_HEADER) ) #endif temp = p->TxCount; if ( temp >= MAX_UDP_DATA ) { UDPFlush(); } #undef MAX_UDP_DATA return TRUE; }
/********************************************************************* * Function: void ARPPut(NODE_INFO* more, BYTE opCode) * * PreCondition: None * * Input: remote - Remote node info * opCode - ARP op code to send * * Output: TRUE - The ARP packet was generated properly * FALSE - Unable to allocate a TX buffer * * Side Effects: None * * Overview: None * * Note: None ********************************************************************/ BOOL ARPPut(NODE_INFO *remote, BYTE opCode) { ARP_PACKET packet; BUFFER MyTxBuffer; MyTxBuffer = MACGetTxBuffer(TRUE); // Do not respond if there is no room to generate the ARP reply if(MyTxBuffer == INVALID_BUFFER) return FALSE; MACSetTxBuffer(MyTxBuffer, 0); packet.HardwareType = HW_ETHERNET; packet.Protocol = ARP_IP; packet.MACAddrLen = sizeof(MAC_ADDR); packet.ProtocolLen = sizeof(IP_ADDR); if ( opCode == ARP_REQUEST ) { packet.Operation = ARP_OPERATION_REQ; packet.TargetMACAddr.v[0] = 0xff; packet.TargetMACAddr.v[1] = 0xff; packet.TargetMACAddr.v[2] = 0xff; packet.TargetMACAddr.v[3] = 0xff; packet.TargetMACAddr.v[4] = 0xff; packet.TargetMACAddr.v[5] = 0xff; } else { packet.Operation = ARP_OPERATION_RESP; packet.TargetMACAddr = remote->MACAddr; } packet.SenderMACAddr = AppConfig.MyMACAddr; packet.SenderIPAddr = AppConfig.MyIPAddr; // Check to see if target is on same subnet, if not, find Gateway MAC. // Once we get Gateway MAC, all access to remote host will go through Gateway. if((packet.SenderIPAddr.Val ^ remote->IPAddr.Val) & AppConfig.MyMask.Val) { packet.TargetIPAddr = AppConfig.MyGateway; } else packet.TargetIPAddr = remote->IPAddr; SwapARPPacket(&packet); MACPutHeader(&packet.TargetMACAddr, MAC_ARP, sizeof(packet)); //MACPutArray((int8*)&packet, sizeof(packet)); MACPutArray(&packet, sizeof(ARP_PACKET)); MACFlush(); return TRUE; }
/** * Given number of data bytes from the given array are put into the UDP transmit buffer * and active UDP socket buffer length is incremented by number of bytes. The data is * NOT sent yet, and the UDPFlush() function must be called to send all data contained * in the transmit buffer. * * If there is not enough space in the transmit buffer for all the data, the contents of * the transmit buffer will be sent, and this function will return the actual amount of * bytes that were sent. In this case, it is VERY IMPORTANT to call the UDPIsPutReady() * function again before calling the UDPPut() or UDPPutArray() functions! This will however * only happen if the transmit buffer fills up. The transmit buffer for UDP data is * = (MAC_TX_BUFFER_SIZE - 42), which is usually 982 bytes. If writing less then this to * the transmit buffer before calling UDPFlush(), then this function will always return the * requested number of bytes! * * Note: This function loads data into an active UDP socket as determined by previous * call to UDPIsPutReady(). * * @preCondition UDPIsPutReady() == TRUE with desired UDP socket * that is to be loaded. * * @param[in] buffer Buffer containing data that has to be sent. * @param count Number of bytes to send * * @return Number of bytes added to the transmit buffer.<br> * !!!!! IMPORTANT !!!!!<br> * If this value is less then the number of bytes we requested to send, then * UDPIsPutReady() must be called again before calling the UDPPut() or * UDPPutArray() functions! */ WORD UDPPutArray(BYTE *buffer, WORD count) { UDP_SOCKET_INFO *p; WORD temp; WORD ckCount = 0; p = &UDPSocketInfo[activeUDPSocket]; //This UDP Socket does not contain any unsent data, and currently does not own a TX Buffer! //Assign it the next available TX Buffer if ( p->TxCount == 0 ) { //Get handle to next available TX Buffer. The UDPIsPutReady() function that has to be called //prior to this function will determine if there is an available TX Buffer. p->TxBuffer = MACGetTxBuffer(TRUE); // Make sure that we received a TX buffer if(p->TxBuffer == INVALID_BUFFER) return FALSE; //This sets the current TX Buffer pointer to the given offset after the IP header. //We give the size of the UDP header here as a parameter. This causes the current //write pointer to be set to firt byte after the UDP header, which is the UDP data //area. IPSetTxBuffer(p->TxBuffer, sizeof(UDP_HEADER)); } //This function request more bytes to be written to the TX Buffer then there is space if ((p->TxCount + count) > UDPGetMaxDataLength()) { //Update count with maximum number of bytes that there is place for in the TX Buffer count = UDPGetMaxDataLength() - p->TxCount; } //Write buffer MACPutArray(buffer, count); while (ckCount <= count) { if (p->TxCount+ckCount & 1) { udpChecksum += *(buffer+ckCount); } else { udpChecksum += ((WORD)*(buffer+ckCount) << 8); } ckCount++; } //Keep track of number of bytes loaded. //If total bytes fill up buffer, transmit it. p->TxCount += count; if ( p->TxCount >= UDPGetMaxDataLength() ) { UDPFlush(); } return count; //Return actual number of bytes sent }
/** * A ICMP packet is created and put on MAC. * * @preCondition ICMPIsTxReady() == TRUE * * @param remote Remote node info * @param code ICMP_ECHO_REPLY or ICMP_ECHO_REQUEST * @param data Data bytes * @param len Number of bytes to send * @param id ICMP identifier * @param seq ICMP sequence number */ void ICMPPut(NODE_INFO *remote, ICMP_CODE code, BYTE *data, BYTE len, WORD id, WORD seq) { ICMP_PACKET packet; WORD ICMPLen; BUFFER MyTxBuffer; MyTxBuffer = MACGetTxBuffer(TRUE); // Abort if there is no where in the Ethernet controller to // store this packet. if(MyTxBuffer == INVALID_BUFFER) return; IPSetTxBuffer(MyTxBuffer, 0); ICMPLen = ICMP_HEADER_SIZE + (WORD)len; packet.Code = 0; packet.Type = code; packet.Checksum = 0; packet.Identifier = id; packet.SequenceNumber = seq; memcpy((void*)packet.Data, (void*)data, len); SwapICMPPacket(&packet); #if defined(NON_MCHP_MAC) //This is NOT a Microchip MAC packet.Checksum = CalcIPChecksum((BYTE*)&packet, ICMPLen); #endif IPPutHeader(remote, IP_PROT_ICMP, (WORD)(ICMP_HEADER_SIZE + len)); IPPutArray((BYTE*)&packet, ICMPLen); #if !defined(NON_MCHP_MAC) //This is a Microchip MAC // Calculate and write the ICMP checksum using the Microchip MAC's DMA packet.Checksum = MACCalcTxChecksum(sizeof(IP_HEADER), ICMPLen); IPSetTxBuffer(MyTxBuffer, 2); MACPutArray((BYTE*)&packet.Checksum, 2); #endif MACFlush(); }
/** * Given data byte is put into the UDP transmit buffer and active UDP socket buffer * length is incremented. The data is NOT sent yet, and the UDPFlush() function must * be called to send all data contained in the transmit buffer. * * If the transmit buffer filled up, the contents of the transmit buffer will be sent, * and this function will return FALSE. In this case, it is VERY IMPORTANT to call the * UDPIsPutReady() function again before calling the UDPPut() or UDPPutArray() functions! * * Note: This function loads data into an active UDP socket as determined by previous * call to UDPIsPutReady(). * * @preCondition UDPIsPutReady() == TRUE with desired UDP socket * that is to be loaded. * * @param v - Data byte to loaded into transmit buffer * * @return TRUE if transmit buffer is still ready to accept more data bytes <br> * FALSE if transmit buffer can no longer accept any more data byte.<br> * If FALSE is returned, then UDPIsPutReady() has to be called again before * calling the UDPPut() or UDPPutArray() functions! */ BOOL UDPPut(BYTE v) { UDP_SOCKET_INFO *p; p = &UDPSocketInfo[activeUDPSocket]; //This UDP Socket does not contain any unsent data, and currently does not own a TX Buffer! //Assign it the next available TX Buffer if ( p->TxCount == 0 ) { // This is the very first byte that is loaded in UDP buffer. // Remember what transmit buffer we are loading, and // start loading this and next bytes in data area of UDP packet. p->TxBuffer = MACGetTxBuffer(TRUE); // Make sure that we received a TX buffer if(p->TxBuffer == INVALID_BUFFER) return FALSE; //This sets the current TX Buffer pointer to the given offset after the IP header. //We give the size of the UDP header here as a parameter. This causes the current //write pointer to be set to firt byte after the UDP header, which is the UDP data area. IPSetTxBuffer(p->TxBuffer, sizeof(UDP_HEADER)); udpChecksum = 0; //p->TxOffset = 0; /* TxOffset is not required! */ } //Load it. MACPut(v); if (p->TxCount & 1) { udpChecksum += v; } else { udpChecksum += ((WORD)v << 8); } //Keep track of number of bytes loaded. //If total bytes fill up buffer, transmit it. p->TxCount++; if ( p->TxCount >= UDPGetMaxDataLength() ) { UDPFlush(); udpChecksum = 0; } return TRUE; }
/********************************************************************* * Function: BOOL UDPPut(BYTE v) * * PreCondition: UDPIsPutReady() == TRUE with desired UDP socket * that is to be loaded. * * Input: v - Data byte to loaded into transmit buffer * * Output: TRUE if transmit buffer is still ready to accept * more data bytes * * FALSE if transmit buffer can no longer accept * any more data byte. * * Side Effects: None * * Overview: Given data byte is put into UDP transmit buffer * and active UDP socket buffer length is incremented * by one. * If buffer has become full, FALSE is returned. * Or else TRUE is returned. * * Note: This function loads data into an active UDP socket * as determined by previous call to UDPIsPutReady() ********************************************************************/ BOOL UDPPut(BYTE v) { UDP_SOCKET_INFO *p; WORD temp; WORD tempOffset; WORD tempCount; p = &UDPSocketInfo[activeUDPSocket]; tempCount=p->TxCount; if ( tempCount == 0 ) { // This is the very first byte that is loaded in UDP buffer. // Remember what transmit buffer we are loading, and // start loading this and next bytes in data area of UDP packet. p->TxBuffer = MACGetTxBuffer(TRUE); // Make sure that we received a TX buffer if(p->TxBuffer == INVALID_BUFFER) return FALSE; IPSetTxBuffer(p->TxBuffer, sizeof(UDP_HEADER)); p->TxOffset = 0; } tempOffset=p->TxOffset; /*if (v>=0x20) debug_udp("-%c", v); else debug_udp("-0x%X", v);*/ // Load it. MACPut(v); // Keep track of number of bytes loaded. // If total bytes fill up buffer, transmit it. if (tempOffset >= tempCount) { tempCount++; } tempOffset++; /* //broken in ccs? if ( p->TxOffset++ >= p->TxCount ) { p->TxCount++; debug_udp("!"); } */ #define SIZEOF_MAC_HEADER (14) // Depending on what communication media is used, allowable UDP // data length will vary. #if STACK_USE_SLIP #define MAX_UDP_DATA (MAC_TX_BUFFER_SIZE - SIZEOF_MAC_HEADER - sizeof(IP_HEADER) - sizeof(UDP_HEADER)) #else #define MAX_UDP_DATA (MAC_TX_BUFFER_SIZE - sizeof(IP_HEADER) - sizeof(UDP_HEADER) ) #endif p->TxOffset = tempOffset; //temp = p->TxCount; //if ( temp >= MAX_UDP_DATA ) p->TxCount = tempCount; if (tempCount >= MAX_UDP_DATA) { UDPFlush(); } #undef MAX_UDP_DATA return TRUE; }