/** * Handler called from the UDP stack. If message is relevant, then send * back a reply. Return 1 tells UDP stack not to copy this into a * client buffer; it has already been taken care of-thank you. * * RETURN: 1 = handler has done all relevant processing for datagram. */ int echo_handler(int event, udp_Socket * s, ll_Gather * g, _udp_datagram_info * udi) { // Datagram has come in. It is in the Ethernet receive buffer. No need to // copy it anywhere - we just transmit it straight back to the sender. // The relevant information comes in the following fields (not all of which // we use here) (see LIB\tcpip\net.lib for structure): // g->data1 -> IP and UDP headers (root) // g->len1 -> IP and UDP header length // g->data2 -> UDP datagram data (far) - first buffer // g->len2 -> UDP datagram data length - first buffer // g->data3 -> UDP datagram data (far) - second buffer ** // g->len3 -> UDP datagram data length - second buffer // udi->remip -> sender's IP address // udi->remport -> sender's UDP port number // udi->flags -> flags. // ** Note: prior to Dynamic C 9.0, only one buffer would be provided (i.e. g->data3 would // always be zero). From DC9.0, it is now possible for the incoming data to be split into // two areas. // The 'event' parameter determines the type of event. As of DC 7.30, this is either // UDP_DH_INDATA : incoming datagram // UDP_DH_ICMPMSG : incoming ICMP message. if (event == UDP_DH_ICMPMSG) { return 1; // Just ignore incoming ICMP errors. } // Otherwise, bounce the packet back! We ignore errors because this // is UDP, and the sender will try again. Not a good idea in general, though. printf("Got UDP len1=%2u len2=%4u len3=%4u remip=%08lX remport=%5u len=%u\n", g->len1, g->len2, g->len3, udi->remip, udi->remport, udi->len); if (!g->len3) // No second buffer. This is easy - just use udp_sendto directly udp_sendto(s, g->data2, g->len2, udi->remip, udi->remport); else { // Awkward: got 2 areas, so copy them into a contiguous root buffer and send. _f_memcpy(pktbuf, g->data2, g->len2); _f_memcpy(pktbuf + g->len2, g->data3, g->len3); udp_sendto(s, pktbuf, g->len2+g->len3, udi->remip, udi->remport); } // Return 1 to indicate that all processing has been done. No copy to // normal udp socket receive buffer. return 1; }
/* START FUNCTION DESCRIPTION ******************************************** xbee_disc_nd_parse <xbee_discovery.c> SYNTAX: int xbee_disc_nd_parse( xbee_node_id_t FAR *parsed, const void FAR *source) DESCRIPTION: Parse a Node Discovery response and store it in an xbee_node_id_t structure. **************************************************************************/ int xbee_disc_nd_parse( xbee_node_id_t FAR *parsed, const void FAR *source) { int ni_len; const xbee_node_id1_t FAR *id1; const xbee_node_id2_t FAR *id2; if (parsed == NULL || source == NULL) { return -EINVAL; } id1 = (const xbee_node_id1_t FAR *) source; ni_len = strlen( id1->node_info); if (ni_len > XBEE_DISC_MAX_NODEID_LEN) { return -EINVAL; } id2 = (const xbee_node_id2_t FAR *) &id1->node_info[ni_len + 1]; parsed->ieee_addr_be = id1->ieee_addr_be; parsed->network_addr = be16toh( id1->network_addr_be); parsed->parent_addr = be16toh( id2->parent_addr_be); parsed->device_type = id2->device_type; _f_memset( parsed->node_info, 0, sizeof(parsed->node_info)); _f_memcpy( parsed->node_info, id1->node_info, ni_len); return 0; }
/* START FUNCTION DESCRIPTION ******************************************** wpan_envelope_reply <wpan_aps.c> SYNTAX: int wpan_envelope_reply( wpan_envelope_t FAR *reply, const wpan_envelope_t FAR *original) DESCRIPTION: Create a reply envelope based on the envelope received from a remote node. Copies the interface, addresses, profile and cluster from the original envelope, and then swaps the source and destination endpoints. Note that it may be necessary for the caller to change the <cluster_id> as well, after building the reply envelope. For example, ZDO responses set the high bit of the request's cluster ID. PARAMETER1: reply - Buffer for storing the reply envelope. PARAMETER2: original - Original envelope, received from a remote node, to base the reply on. RETURNS: 0 - addressed reply envelope -EINVAL - either parameter is \c NULL or they point to the same address SEE ALSO: wpan_envelope_create() **************************************************************************/ wpan_aps_debug int wpan_envelope_reply( wpan_envelope_t FAR *reply, const wpan_envelope_t FAR *original) { if (! (reply && original) || original == reply) { return -EINVAL; } // Copy dev, ieee_address, network_address, profile_id, and cluster_id. _f_memcpy( reply, original, offsetof( wpan_envelope_t, source_endpoint)); // swap source and destination endpoints reply->source_endpoint = original->dest_endpoint; reply->dest_endpoint = original->source_endpoint; // Use APS encryption if replying to an encrypted frame. reply->options = (original->options & WPAN_ENVELOPE_RX_APS_ENCRYPT) ? WPAN_CLUST_FLAG_ENCRYPT : 0; // Clear payload reply->payload = NULL; reply->length = 0; return 0; }
/**************************************************************************** scan_assoc_callback Much like scan_callback above, this function is called as a result of a Wi-Fi scan. The main difference is that this function gives the user the option of associating with one of the BSS's. It uses scan_callback above to sort and print the scan results. Inputs: data -- far pointer to wifi_scan_data structure, which contains a count of the number of responses, and an array of _wifi_wln_scan_bss structures, with the first `count' containing valid data for the responses. ****************************************************************************/ root void scan_assoc_callback(far wifi_scan_data* data) { char c, ssid[WLN_SSID_SIZE+1]; int ssid_len; far _wifi_wln_scan_bss *bss; // Sort and print the scan results scan_callback(data); bss = data->bss; printf("\nSelect a new BSS or quit ([0-%x, q to quit)]\n", data->count-1); while (1) { tcp_tick(NULL); // While we're waiting, continue to tick. if (kbhit()) { c = getchar(); // Echo the character printf("%c\n", c); // Convert character to numeric value. if ('0' <= c && c <= '9') { c = c - '0'; } else if (isxdigit(c)) { c = (tolower(c) - 'a' + 10); } else if (tolower(c) == 'q') { printf("Quitting scan selection\n"); break; } if (c >= data->count) { printf("Unlisted option, quitting...\n"); break; } // c is now the index of the BSS the user opted to associate with bss = &(data->bss[c]); ssid_len = bss->ssid_len; // Need near copy of SSID to call ifconfig. ssid will be promoted to // far for this call, but the results will be in ssid as a near // variable _f_memcpy(ssid, bss->ssid, ssid_len); #ifdef IFC_WIFI_WPA_PSK_PASSPHRASE printf("Resetting the passphrase--this will take some time.\n"); #endif // Set the SSID. Also, if a passphrase has been defined as a macro, // then reconfigure the passphrase. This is necessary because the // passphrase and SSID together are used to generate the key. If the // SSID changes, then the generated key must change. Note that // regenerating the key will take about another 20 seconds on an // RCM54xxW. if (ifconfig (IF_WIFI0, IFS_WIFI_SSID, ssid_len, ssid, #ifdef IFC_WIFI_WPA_PSK_PASSPHRASE IFS_WIFI_WPA_PSK_PASSPHRASE, IFC_WIFI_WPA_PSK_PASSPHRASE, #endif IFS_END)) { printf (" error setting SSID\n"); } wifi_ssid_to_str (ssid, ssid, ssid_len); printf("Selected BSS is [%s]. Wait a bit, then check MAC status\n", ssid); break; } } }
int xbee_ipv4_envelope_reply(xbee_ipv4_envelope_t FAR *reply, const xbee_ipv4_envelope_t FAR *original) { if (!reply || !original) { return -EINVAL; } _f_memcpy(reply, original, offsetof(xbee_ipv4_envelope_t, options)); _f_memset(&reply->options, 0x00, sizeof *reply - offsetof(xbee_ipv4_envelope_t, options)); return 0; }
int main() { static far long long_var; static far float float_var; static far int int_var; far char * ptr; // use %ls to print a string stored in FAR printf("This is the message stored in FAR: %ls\n\n", msg); _f_strcpy(far_buffer, msg); ptr = _f_strchr(far_buffer, ' '); _f_strcpy(ptr, " Rabbit!"); printf("This is the new message stored in FAR: %ls\n\n", far_buffer); // near_buffer is upcast automatically. _f_memcpy(near_buffer, far_buffer, strlen(far_buffer) + 1); printf("This is the new message stored in NEAR: %s\n\n", near_buffer); if(strcmp(far_buffer, near_buffer) != 0) { printf("Error, strcmp says the strings are different!\n"); } // Lets convert some numbers. _f_strcpy(far_buffer, "16E7B 3.141593 120"); // ptr MUST be of type far char * long_var = _f_strtol(far_buffer, &ptr, 16); float_var = _f_strtod(ptr, &ptr); int_var = atoi(ptr); printf("%ls => %lX %f %d\n", far_buffer, long_var, float_var, int_var); }
void _xbee_set_unaligned32( void FAR *p, uint32_t value) { _f_memcpy(p, &value, 4); }
void _xbee_set_unaligned16( void FAR *p, uint16_t value) { _f_memcpy(p, &value, 2); }
uint32_t _xbee_get_unaligned32( const void FAR *p) { uint32_t retval; _f_memcpy(&retval, p, 4); return retval; }
uint16_t _xbee_get_unaligned16( const void FAR *p) { uint16_t retval; _f_memcpy(&retval, p, 2); return retval; }
// This function must be declared with "useix" since the PUSH IP in // _PBF_LOWER() breaks all stack references (C or assembly) using SP. nodebug useix int pbf_far_Read(void __far *dest, unsigned long offset, int bytes) { auto long block; auto int copy; auto int copied; auto unsigned char __far *buffer = dest; #if !_RUN_FROM_RAM // Boards running from flash are very easy -- PBF is mapped to 0x000000. _f_memcpy(buffer, (void __far *) offset, bytes); return bytes; #else #if _RUN_FROM_RAM && (MSB_BIT != 20) #error "This code was written on the assumption that memory is mapped" #error "in 512KB blocks. Any change to that assumption should result" #fatal "in changes to this code." #endif // If reading from parallel flash, it's mapped in at MB3CR. // On RCM5450W and other devices with 1MB of program flash, need to flip a // bit in MB3CR to get at the lower 512KB of the flash. copied = 0; // Are there any bytes left to read in the lower 512KB of flash? block = 512ul * 1024 - offset; if (block > 0) { copy = (block > bytes) ? bytes : (int) block; _PBF_LOWER(); // map in lower 512KB of parallel flash // 0x180000 = 1.5MB, the physical address of MB3. _f_memcpy (buffer, (char __far *) (0x180000 + offset), copy); _PBF_UPPER(); // map upper half of parallel flash back offset += copy; copied += copy; buffer += copy; bytes -= copy; } // if the parallel flash is larger than 512KB, check for bytes to read #if _FLASH_SIZE_ > 512/4 if (bytes) { // still have bytes to copy, from upper 512KB of parallel flash block = 1024ul * 1024 - offset; if (bytes > block) { bytes = (int) block; } // When reading upper 512KB of flash, use 0x100000 as offset since // we've mapped the upper 512KB of the 1MB flash in at 0x180000. // In this code, offset >= 0x080000 _f_memcpy (buffer, (char __far *) (0x100000 + offset), bytes); copied += bytes; } #endif return copied ? copied : -EEOF; #endif }