/* $Id: plugin_wireless.c,v 1.9 2005/05/08 04:32:45 reinelt Exp $ * * Wireless Extension plugin * * Copyright (C) 2004 Xavier Vello * Copyright (C) 2004 Martin Hejl * Copyright (C) 2004 The LCD4Linux Team * * Losts of code borrowed from Wireless Tools, which is * Copyright (C) 1997-2002 Jean Tourrilhes * (avaible at http://web.hpl.hp.com/personal/Jean_Tourrilhes/Linux/) * * This file is part of LCD4Linux. * * LCD4Linux is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2, or (at your option) * any later version. * * LCD4Linux is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. * * * $Log: plugin_wireless.c,v $ * Revision 1.9 2005/05/08 04:32:45 reinelt * CodingStyle added and applied * * Revision 1.8 2005/01/18 06:30:23 reinelt * added (C) to all copyright statements * * Revision 1.7 2004/06/26 12:05:00 reinelt * * uh-oh... the last CVS log message messed up things a lot... * * Revision 1.6 2004/06/26 09:27:21 reinelt * * added '-W' to CFLAGS * changed all C++ comments to C ones * cleaned up a lot of signed/unsigned mistakes * * Revision 1.5 2004/06/20 10:09:56 reinelt * * 'const'ified the whole source * * Revision 1.4 2004/06/17 06:23:43 reinelt * * hash handling rewritten to solve performance issues * * Revision 1.3 2004/05/27 03:39:47 reinelt * * changed function naming scheme to plugin::function * * Revision 1.2 2004/04/17 13:05:58 nicowallmeier * minor bugfix * * Revision 1.1 2004/04/07 08:29:05 hejl * New plugin for wireless info * */ /* * Exported functions: wifi_level wifi_noise wifi_quality wifi_protocol wifi_frequency wifi_bitrate wifi_essid wifi_op_mode wifi_sensitivity wifi_sec_mode All Functions take one parameter (the name of the device, like "wlan0", "ath0" and so on) */ #include "config.h" #include #include #include #include #include #include #include #include #include "debug.h" #include "plugin.h" #include "cfg.h" #include "hash.h" #include "qprintf.h" #ifdef WITH_DMALLOC #include #endif #define HASH_TTL 100 /*#define KILO 1e3 */ /*#define MEGA 1e6 */ /*#define GIGA 1e9 */ #define KEY_LEVEL "level" #define KEY_QUALITY "quality" #define KEY_NOISE "noise" #define KEY_PROTO "proto" #define KEY_FREQUENCY "frequency" #define KEY_BIT_RATE "bit_rate" #define KEY_ESSID "essid" #define KEY_OP_MODE "op_mode" #define KEY_SENS "sens" #define KEY_SEC_MODE "sec_mode" #define FREQ2FLOAT(m,e) (((double) m) * pow(10,e)) #define MWATT2DBM(in) ((int) (ceil(10.0 * log10((double) in)))) static HASH wireless; static int sock = -2; static char *operation_mode[] = { "Auto", "Ad-Hoc", "Managed", "Master", "Repeater", "Secondary", "Monitor", "n/a" }; static void ioctl_error(const int line) { error("IOCTL call to wireless extensions in line %d returned error", line); } int do_ioctl(const int sock, /* Socket to the kernel */ const char *ifname, /* Device name */ const int request, /* WE ID */ struct iwreq *pwrq) { /* Fixed part of the request */ /* Set device name */ strncpy(pwrq->ifr_name, ifname, IFNAMSIZ); /* Do the request */ return (ioctl(sock, request, pwrq)); } int get_range_info(const int sock, const char *ifname, struct iw_range *range) { struct iwreq req; char buffer[sizeof(struct iw_range) * 2]; /* Large enough */ if (sock <= 0) { return (-1); } /* Cleanup */ memset(buffer, 0, sizeof(buffer)); req.u.data.pointer = (caddr_t) buffer; req.u.data.length = sizeof(buffer); req.u.data.flags = 0; if (do_ioctl(sock, ifname, SIOCGIWRANGE, &req) < 0) return (-1); /* Copy stuff at the right place, ignore extra */ memcpy((char *) range, buffer, sizeof(struct iw_range)); return (0); } static int get_ifname(struct iwreq *preq, const char *dev) { /* do not cache this call !!! */ struct iwreq req; char key_buffer[32]; if (sock <= 0) { return (-1); } qprintf(key_buffer, sizeof(key_buffer), "%s.%s", dev, KEY_PROTO); if (!preq) preq = &req; if (do_ioctl(sock, dev, SIOCGIWNAME, preq)) { debug("%s isn't a wirelesss interface !", dev); return -1; } hash_put(&wireless, key_buffer, preq->u.name); return (0); } static int get_frequency(const char *dev, const char *key) { /* Get frequency / channel */ struct iwreq req; char qprintf_buffer[1024]; char key_buffer[32]; double freq; int age; qprintf(key_buffer, sizeof(key_buffer), "%s.%s", dev, key); age = hash_age(&wireless, key); /* reread every HASH_TTL msec only */ if (age > 0 && age <= HASH_TTL) { return (0); } if (get_ifname(&req, dev) != 0) { return (-1); } req.u.data.length = 0; req.u.data.flags = 1; /* Clear updated flag */ if (do_ioctl(sock, dev, SIOCGIWFREQ, &req) < 0) { ioctl_error(__LINE__); return -1; } freq = FREQ2FLOAT(req.u.freq.m, req.u.freq.e); /*if( freq>= GIGA) snprintf(qprintf_buffer,sizeof(qprintf_buffer), "%g GHz", freq / GIGA); else if(freq>= MEGA) snprintf(qprintf_buffer,sizeof(qprintf_buffer), "%g MHz", freq / MEGA); else snprintf(qprintf_buffer,sizeof(qprintf_buffer), "%g kHz", freq / KILO); */ snprintf(qprintf_buffer, sizeof(qprintf_buffer), "%g", freq); hash_put(&wireless, key_buffer, qprintf_buffer); return (0); } static int get_essid(const char *dev, const char *key) { /* Get ESSID */ struct iwreq req; char key_buffer[32]; char essid_buffer[IW_ESSID_MAX_SIZE + 1]; int age; qprintf(key_buffer, sizeof(key_buffer), "%s.%s", dev, key); age = hash_age(&wireless, key); /* reread every HASH_TTL msec only */ if (age > 0 && age <= HASH_TTL) { return (0); } if (get_ifname(&req, dev) != 0) { return (-1); } memset(essid_buffer, 0, sizeof(essid_buffer)); req.u.essid.pointer = (caddr_t) essid_buffer; req.u.essid.length = IW_ESSID_MAX_SIZE + 1; req.u.essid.flags = 0; if (do_ioctl(sock, dev, SIOCGIWESSID, &req) < 0) { ioctl_error(__LINE__); return -1; } hash_put(&wireless, key_buffer, essid_buffer); return (0); } static int get_op_mode(const char *dev, const char *key) { /* Get operation mode */ struct iwreq req; char key_buffer[32]; int age; qprintf(key_buffer, sizeof(key_buffer), "%s.%s", dev, key); age = hash_age(&wireless, key); /* reread every HASH_TTL msec only */ if (age > 0 && age <= HASH_TTL) { return (0); } if (get_ifname(&req, dev) != 0) { return (-1); } if (do_ioctl(sock, dev, SIOCGIWMODE, &req) < 0) { ioctl_error(__LINE__); return -1; } /* Fixme: req.u.mode is unsigned and therefore never < 0 */ /* if((req.u.mode > 6) || (req.u.mode < 0)) { */ if (req.u.mode > 6) { req.u.mode = 7; /* mode not available */ } hash_put(&wireless, key_buffer, operation_mode[req.u.mode]); return (0); } static int get_bitrate(const char *dev, const char *key) { /* Get bit rate */ struct iwreq req; char key_buffer[32]; char bitrate_buffer[64]; int age; double bitrate = 0; qprintf(key_buffer, sizeof(key_buffer), "%s.%s", dev, key); age = hash_age(&wireless, key); /* reread every HASH_TTL msec only */ if (age > 0 && age <= HASH_TTL) { return (0); } if (get_ifname(&req, dev) != 0) { return (-1); } if (do_ioctl(sock, dev, SIOCGIWRATE, &req) < 0) { ioctl_error(__LINE__); return -1; } bitrate_buffer[0] = '\0'; bitrate = (double) (req.u.bitrate.value); /* if( bitrate>= GIGA) snprintf(bitrate_buffer,sizeof(bitrate_buffer), "%gGb/s", bitrate / GIGA); else if(bitrate >= MEGA) snprintf(bitrate_buffer,sizeof(bitrate_buffer), "%gMb/s", bitrate / MEGA); else snprintf(bitrate_buffer,sizeof(bitrate_buffer), "%gkb/s", bitrate / KILO); */ snprintf(bitrate_buffer, sizeof(bitrate_buffer), "%g", bitrate); hash_put(&wireless, key_buffer, bitrate_buffer); return (0); } static int get_sens(const char *dev, const char *key) { /* Get sensitivity */ struct iwreq req; struct iw_range range; char key_buffer[32]; char buffer[64]; int age; int has_sens = 0; int has_range = 0; qprintf(key_buffer, sizeof(key_buffer), "%s.%s", dev, key); age = hash_age(&wireless, key); /* reread every HASH_TTL msec only */ if (age > 0 && age <= HASH_TTL) { return (0); } if (get_ifname(&req, dev) != 0) { return (-1); } if (do_ioctl(sock, dev, SIOCGIWSENS, &req) >= 0) { has_sens = 1; } if (get_range_info(sock, dev, &range) < 0) { memset(&range, 0, sizeof(range)); } else { has_range = 1; } if (has_range) { if (req.u.sens.value < 0) { qprintf(buffer, sizeof(buffer), "%d dBm", req.u.sens.value); } else { qprintf(buffer, sizeof(buffer), "%d/%d", req.u.sens.value, range.sensitivity); } } else { qprintf(buffer, sizeof(buffer), "%d", req.u.sens.value); } hash_put(&wireless, key_buffer, buffer); return (0); } static int get_sec_mode(const char *dev, const char *key) { /* Get encryption information */ struct iwreq req; char key_buffer[32]; char encrypt_key[IW_ENCODING_TOKEN_MAX + 1]; int age; int has_key = 0; int key_flags = 0; int key_size = 0; qprintf(key_buffer, sizeof(key_buffer), "%s.%s", dev, key); age = hash_age(&wireless, key); /* reread every HASH_TTL msec only */ if (age > 0 && age <= HASH_TTL) { return (0); } if (get_ifname(&req, dev) != 0) { return (-1); } req.u.data.pointer = (caddr_t) & encrypt_key; req.u.data.length = IW_ENCODING_TOKEN_MAX; req.u.data.flags = 0; if (do_ioctl(sock, dev, SIOCGIWENCODE, &req) >= 0) { has_key = 1; key_flags = req.u.data.flags; key_size = req.u.data.length; } else { return (-1); } /* Display encryption information */ /*if(has_key && (key_flags & IW_ENCODE_INDEX) > 1) */ /* printf(" [%d]", info->key_flags & IW_ENCODE_INDEX); */ if (has_key && (key_flags & IW_ENCODE_RESTRICTED)) hash_put(&wireless, key_buffer, "restricted"); else if (has_key && (key_flags & IW_ENCODE_OPEN)) hash_put(&wireless, key_buffer, "open"); return (0); } static int get_stats(const char *dev, const char *key) { struct iw_statistics stats; struct iwreq req; char qprintf_buffer[1024]; char key_buffer[32]; int age; struct iw_range range; qprintf(key_buffer, sizeof(key_buffer), "%s.%s", dev, key); age = hash_age(&wireless, key); /* reread every HASH_TTL msec only */ if (age > 0 && age <= HASH_TTL) { return (0); } if (get_ifname(&req, dev) != 0) { return (-1); } req.u.data.pointer = (caddr_t) & stats; req.u.data.length = 0; req.u.data.flags = 1; /* Clear updated flag */ if (do_ioctl(sock, dev, SIOCGIWSTATS, &req) < 0) { ioctl_error(__LINE__); return -1; } if (get_range_info(sock, dev, &range) < 0) memset(&range, 0, sizeof(range)); if (stats.qual.level > range.max_qual.level) { qprintf(qprintf_buffer, sizeof(qprintf_buffer), "%d", stats.qual.level - 0x100); qprintf(key_buffer, sizeof(key_buffer), "%s.%s", dev, KEY_LEVEL); hash_put(&wireless, key_buffer, qprintf_buffer); qprintf(qprintf_buffer, sizeof(qprintf_buffer), "%d", stats.qual.noise - 0x100); qprintf(key_buffer, sizeof(key_buffer), "%s.%s", dev, KEY_NOISE); hash_put(&wireless, key_buffer, qprintf_buffer); qprintf(qprintf_buffer, sizeof(qprintf_buffer), "%d/%d", stats.qual.qual, range.max_qual.qual); qprintf(key_buffer, sizeof(key_buffer), "%s.%s", dev, KEY_QUALITY); hash_put(&wireless, key_buffer, qprintf_buffer); } else { qprintf(qprintf_buffer, sizeof(qprintf_buffer), "%d/%d",
#
#	Name:             ISO/IEC 8859-3:1999 to Unicode
#	Unicode version:  3.0
#	Table version:    1.0
#	Table format:     Format A
#	Date:             1999 July 27
#	Authors:          Ken Whistler <kenw@sybase.com>
#
#	Copyright (c) 1991-1999 Unicode, Inc.  All Rights reserved.
#
#	This file is provided as-is by Unicode, Inc. (The Unicode Consortium).
#	No claims are made as to fitness for any particular purpose.  No
#	warranties of any kind are expressed or implied.  The recipient
#	agrees to determine applicability of information provided.  If this
#	file has been provided on optical media by Unicode, Inc., the sole
#	remedy for any claim will be exchange of defective media within 90
#	days of receipt.
#
#	Unicode, Inc. hereby grants the right to freely use the information
#	supplied in this file in the creation of products supporting the
#	Unicode Standard, and to make copies of this file in any form for
#	internal or external distribution as long as this notice remains
#	attached.
#
#	General notes:
#
#	This table contains the data the Unicode Consortium has on how
#       ISO/IEC 8859-3:1999 characters map into Unicode.
#
#	Format:  Three tab-separated columns
#		 Column #1 is the ISO/IEC 8859-3 code (in hex as 0xXX)
#		 Column #2 is the Unicode (in hex as 0xXXXX)
#		 Column #3 the Unicode name (follows a comment sign, '#')
#
#	The entries are in ISO/IEC 8859-3 order.
#
#	Version history
#	1.0 version updates 0.1 version by adding mappings for all
#	control characters.
#
#	Updated versions of this file may be found in:
#		<ftp://ftp.unicode.org/Public/MAPPINGS/>
#
#	Any comments or problems, contact <errata@unicode.org>
#	Please note that <errata@unicode.org> is an archival address;
#	notices will be checked, but do not expect an immediate response.
#
0x00	0x0000	#	NULL
0x01	0x0001	#	START OF HEADING
0x02	0x0002	#	START OF TEXT
0x03	0x0003	#	END OF TEXT
0x04	0x0004	#	END OF TRANSMISSION
0x05	0x0005	#	ENQUIRY
0x06	0x0006	#	ACKNOWLEDGE
0x07	0x0007	#	BELL
0x08	0x0008	#	BACKSPACE
0x09	0x0009	#	HORIZONTAL TABULATION
0x0A	0x000A	#	LINE FEED
0x0B	0x000B	#	VERTICAL TABULATION
0x0C	0x000C	#	FORM FEED
0x0D	0x000D	#	CARRIAGE RETURN
0x0E	0x000E	#	SHIFT OUT
0x0F	0x000F	#	SHIFT IN
0x10	0x0010	#	DATA LINK ESCAPE
0x11	0x0011	#	DEVICE CONTROL ONE
0x12	0x0012	#	DEVICE CONTROL TWO
0x13	0x0013	#	DEVICE CONTROL THREE
0x14	0x0014	#	DEVICE CONTROL FOUR
0x15	0x0015	#	NEGATIVE ACKNOWLEDGE
0x16	0x0016	#	SYNCHRONOUS IDLE
0x17	0x0017	#	END OF TRANSMISSION BLOCK
0x18	0x0018	#	CANCEL
0x19	0x0019	#	END OF MEDIUM
0x1A	0x001A	#	SUBSTITUTE
0x1B	0x001B	#	ESCAPE
0x1C	0x001C	#	FILE SEPARATOR
0x1D	0x001D	#	GROUP SEPARATOR
0x1E	0x001E	#	RECORD SEPARATOR
0x1F	0x001F	#	UNIT SEPARATOR
0x20	0x0020	#	SPACE
0x21	0x0021	#	EXCLAMATION MARK
0x22	0x0022	#	QUOTATION MARK
0x23	0x0023	#	NUMBER SIGN
0x24	0x0024	#	DOLLAR SIGN
0x25	0x0025	#	PERCENT SIGN
0x26	0x0026	#	AMPERSAND
0x27	0x0027	#	APOSTROPHE
0x28	0x0028	#	LEFT PARENTHESIS
0x29	0x0029	#	RIGHT PARENTHESIS
0x2A	0x002A	#	ASTERISK
0x2B	0x002B	#	PLUS SIGN
0x2C	0x002C	#	COMMA
0x2D	0x002D	#	HYPHEN-MINUS
0x2E	0x002E	#	FULL STOP
0x2F	0x002F	#	SOLIDUS
0x30	0x0030	#	DIGIT ZERO
0x31	0x0031	#	DIGIT ONE
0x32	0x0032	#	DIGIT TWO
0x33	0x0033	#	DIGIT THREE
0x34	0x0034	#	DIGIT FOUR
0x35	0x0035	#	DIGIT FIVE
0x36	0x0036	#	DIGIT SIX
0x37	0x0037	#	DIGIT SEVEN
0x38	0x0038	#	DIGIT EIGHT
0x39	0x0039	#	DIGIT NINE
0x3A	0x003A	#	COLON
0x3B	0x003B	#	SEMICOLON
0x3C	0x003C	#	LESS-THAN SIGN
0x3D	0x003D	#	EQUALS SIGN
0x3E	0x003E	#	GREATER-THAN SIGN
0x3F	0x003F	#	QUESTION MARK
0x40	0x0040	#	COMMERCIAL AT
0x41	0x0041	#	LATIN CAPITAL LETTER A
0x42	0x0042	#	LATIN CAPITAL LETTER B
0x43	0x0043	#	LATIN CAPITAL LETTER C
0x44	0x0044	#	LATIN CAPITAL LETTER D
0x45	0x0045	#	LATIN CAPITAL LETTER E
0x46	0x0046	#	LATIN CAPITAL LETTER F
0x47	0x0047	#	LATIN CAPITAL LETTER G
0x48	0x0048	#	LATIN CAPITAL LETTER H
0x49	0x0049	#	LATIN CAPITAL LETTER I
0x4A	0x004A	#	LATIN CAPITAL LETTER J
0x4B	0x004B	#	LATIN CAPITAL LETTER K
0x4C	0x004C	#	LATIN CAPITAL LETTER L
0x4D	0x004D	#	LATIN CAPITAL LETTER M
0x4E	0x004E	#	LATIN CAPITAL LETTER N
0x4F	0x004F	#	LATIN CAPITAL LETTER O
0x50	0x0050	#	LATIN CAPITAL LETTER P
0x51	0x0051	#	LATIN CAPITAL LETTER Q
0x52	0x0052	#	LATIN CAPITAL LETTER R
0x53	0x0053	#	LATIN CAPITAL LETTER S
0x54	0x0054	#	LATIN CAPITAL LETTER T
0x55	0x0055	#	LATIN CAPITAL LETTER U
0x56	0x0056	#	LATIN CAPITAL LETTER V
0x57	0x0057	#	LATIN CAPITAL LETTER W
0x58	0x0058	#	LATIN CAPITAL LETTER X
0x59	0x0059	#	LATIN CAPITAL LETTER Y
0x5A	0x005A	#	LATIN CAPITAL LETTER Z
0x5B	0x005B	#	LEFT SQUARE BRACKET
0x5C	0x005C	#	REVERSE SOLIDUS
0x5D	0x005D	#	RIGHT SQUARE BRACKET
0x5E	0x005E	#	CIRCUMFLEX ACCENT
0x5F	0x005F	#	LOW LINE
0x60	0x0060	#	GRAVE ACCENT
0x61	0x0061	#	LATIN SMALL LETTER A
0x62	0x0062	#	LATIN SMALL LETTER B
0x63	0x0063	#	LATIN SMALL LETTER C
0x64	0x0064	#	LATIN SMALL LETTER D
0x65	0x0065	#	LATIN SMALL LETTER E
0x66	0x0066	#	LATIN SMALL LETTER F
0x67	0x0067	#	LATIN SMALL LETTER G
0x68	0x0068	#	LATIN SMALL LETTER H
0x69	0x0069	#	LATIN SMALL LETTER I
0x6A	0x006A	#	LATIN SMALL LETTER J
0x6B	0x006B	#	LATIN SMALL LETTER K
0x6C	0x006C	#	LATIN SMALL LETTER L
0x6D	0x006D	#	LATIN SMALL LETTER M
0x6E	0x006E	#	LATIN SMALL LETTER N
0x6F	0x006F	#	LATIN SMALL LETTER O
0x70	0x0070	#	LATIN SMALL LETTER P
0x71	0x0071	#	LATIN SMALL LETTER Q
0x72	0x0072	#	LATIN SMALL LETTER R
0x73	0x0073	#	LATIN SMALL LETTER S
0x74	0x0074	#	LATIN SMALL LETTER T
0x75	0x0075	#	LATIN SMALL LETTER U
0x76	0x0076	#	LATIN SMALL LETTER V
0x77	0x0077	#	LATIN SMALL LETTER W
0x78	0x0078	#	LATIN SMALL LETTER X
0x79	0x0079	#	LATIN SMALL LETTER Y
0x7A	0x007A	#	LATIN SMALL LETTER Z
0x7B	0x007B	#	LEFT CURLY BRACKET
0x7C	0x007C	#	VERTICAL LINE
0x7D	0x007D	#	RIGHT CURLY BRACKET
0x7E	0x007E	#	TILDE
0x7F	0x007F	#	DELETE
0x80	0x0080	#	<control>
0x81	0x0081	#	<control>
0x82	0x0082	#	<control>
0x83	0x0083	#	<control>
0x84	0x0084	#	<control>
0x85	0x0085	#	<control>
0x86	0x0086	#	<control>
0x87	0x0087	#	<control>
0x88	0x0088	#	<control>
0x89	0x0089	#	<control>
0x8A	0x008A	#	<control>
0x8B	0x008B	#	<control>
0x8C	0x008C	#	<control>
0x8D	0x008D	#	<control>
0x8E	0x008E	#	<control>
0x8F	0x008F	#	<control>
0x90	0x0090	#	<control>
0x91	0x0091	#	<control>
0x92	0x0092	#	<control>
0x93	0x0093	#	<control>
0x94	0x0094	#	<control>
0x95	0x0095	#	<control>
0x96	0x0096	#	<control>
0x97	0x0097	#	<control>
0x98	0x0098	#	<control>
0x99	0x0099	#	<control>
0x9A	0x009A	#	<control>
0x9B	0x009B	#	<control>
0x9C	0x009C	#	<control>
0x9D	0x009D	#	<control>
0x9E	0x009E	#	<control>
0x9F	0x009F	#	<control>
0xA0	0x00A0	#	NO-BREAK SPACE
0xA1	0x0126	#	LATIN CAPITAL LETTER H WITH STROKE
0xA2	0x02D8	#	BREVE
0xA3	0x00A3	#	POUND SIGN
0xA4	0x00A4	#	CURRENCY SIGN
0xA6	0x0124	#	LATIN CAPITAL LETTER H WITH CIRCUMFLEX
0xA7	0x00A7	#	SECTION SIGN
0xA8	0x00A8	#	DIAERESIS
0xA9	0x0130	#	LATIN CAPITAL LETTER I WITH DOT ABOVE
0xAA	0x015E	#	LATIN CAPITAL LETTER S WITH CEDILLA
0xAB	0x011E	#	LATIN CAPITAL LETTER G WITH BREVE
0xAC	0x0134	#	LATIN CAPITAL LETTER J WITH CIRCUMFLEX
0xAD	0x00AD	#	SOFT HYPHEN
0xAF	0x017B	#	LATIN CAPITAL LETTER Z WITH DOT ABOVE
0xB0	0x00B0	#	DEGREE SIGN
0xB1	0x0127	#	LATIN SMALL LETTER H WITH STROKE
0xB2	0x00B2	#	SUPERSCRIPT TWO
0xB3	0x00B3	#	SUPERSCRIPT THREE
0xB4	0x00B4	#	ACUTE ACCENT
0xB5	0x00B5	#	MICRO SIGN
0xB6	0x0125	#	LATIN SMALL LETTER H WITH CIRCUMFLEX
0xB7	0x00B7	#	MIDDLE DOT
0xB8	0x00B8	#	CEDILLA
0xB9	0x0131	#	LATIN SMALL LETTER DOTLESS I
0xBA	0x015F	#	LATIN SMALL LETTER S WITH CEDILLA
0xBB	0x011F	#	LATIN SMALL LETTER G WITH BREVE
0xBC	0x0135	#	LATIN SMALL LETTER J WITH CIRCUMFLEX
0xBD	0x00BD	#	VULGAR FRACTION ONE HALF
0xBF	0x017C	#	LATIN SMALL LETTER Z WITH DOT ABOVE
0xC0	0x00C0	#	LATIN CAPITAL LETTER A WITH GRAVE
0xC1	0x00C1	#	LATIN CAPITAL LETTER A WITH ACUTE
0xC2	0x00C2	#	LATIN CAPITAL LETTER A WITH CIRCUMFLEX
0xC4	0x00C4	#	LATIN CAPITAL LETTER A WITH DIAERESIS
0xC5	0x010A	#	LATIN CAPITAL LETTER C WITH DOT ABOVE
0xC6	0x0108	#	LATIN CAPITAL LETTER C WITH CIRCUMFLEX
0xC7	0x00C7	#	LATIN CAPITAL LETTER C WITH CEDILLA
0xC8	0x00C8	#	LATIN CAPITAL LETTER E WITH GRAVE
0xC9	0x00C9	#	LATIN CAPITAL LETTER E WITH ACUTE
0xCA	0x00CA	#	LATIN CAPITAL LETTER E WITH CIRCUMFLEX
0xCB	0x00CB	#	LATIN CAPITAL LETTER E WITH DIAERESIS
0xCC	0x00CC	#	LATIN CAPITAL LETTER I WITH GRAVE
0xCD	0x00CD	#	LATIN CAPITAL LETTER I WITH ACUTE
0xCE	0x00CE	#	LATIN CAPITAL LETTER I WITH CIRCUMFLEX
0xCF	0x00CF	#	LATIN CAPITAL LETTER I WITH DIAERESIS
0xD1	0x00D1	#	LATIN CAPITAL LETTER N WITH TILDE
0xD2	0x00D2	#	LATIN CAPITAL LETTER O WITH GRAVE
0xD3	0x00D3	#	LATIN CAPITAL LETTER O WITH ACUTE
0xD4	0x00D4	#	LATIN CAPITAL LETTER O WITH CIRCUMFLEX
0xD5	0x0120	#	LATIN CAPITAL LETTER G WITH DOT ABOVE
0xD6	0x00D6	#	LATIN CAPITAL LETTER O WITH DIAERESIS
0xD7	0x00D7	#	MULTIPLICATION SIGN
0xD8	0x011C	#	LATIN CAPITAL LETTER G WITH CIRCUMFLEX
0xD9	0x00D9	#	LATIN CAPITAL LETTER U WITH GRAVE
0xDA	0x00DA	#	LATIN CAPITAL LETTER U WITH ACUTE
0xDB	0x00DB	#	LATIN CAPITAL LETTER U WITH CIRCUMFLEX
0xDC	0x00DC	#	LATIN CAPITAL LETTER U WITH DIAERESIS
0xDD	0x016C	#	LATIN CAPITAL LETTER U WITH BREVE
0xDE	0x015C	#	LATIN CAPITAL LETTER S WITH CIRCUMFLEX
0xDF	0x00DF	#	LATIN SMALL LETTER SHARP S
0xE0	0x00E0	#	LATIN SMALL LETTER A WITH GRAVE
0xE1	0x00E1	#	LATIN SMALL LETTER A WITH ACUTE
0xE2	0x00E2	#	LATIN SMALL LETTER A WITH CIRCUMFLEX
0xE4	0x00E4	#	LATIN SMALL LETTER A WITH DIAERESIS
0xE5	0x010B	#	LATIN SMALL LETTER C WITH DOT ABOVE
0xE6	0x0109	#	LATIN SMALL LETTER C WITH CIRCUMFLEX
0xE7	0x00E7	#	LATIN SMALL LETTER C WITH CEDILLA
0xE8	0x00E8	#	LATIN SMALL LETTER E WITH GRAVE
0xE9	0x00E9	#	LATIN SMALL LETTER E WITH ACUTE
0xEA	0x00EA	#	LATIN SMALL LETTER E WITH CIRCUMFLEX
0xEB	0x00EB	#	LATIN SMALL LETTER E WITH DIAERESIS
0xEC	0x00EC	#	LATIN SMALL LETTER I WITH GRAVE
0xED	0x00ED	#	LATIN SMALL LETTER I WITH ACUTE
0xEE	0x00EE	#	LATIN SMALL LETTER I WITH CIRCUMFLEX
0xEF	0x00EF	#	LATIN SMALL LETTER I WITH DIAERESIS
0xF1	0x00F1	#	LATIN SMALL LETTER N WITH TILDE
0xF2	0x00F2	#	LATIN SMALL LETTER O WITH GRAVE
0xF3	0x00F3	#	LATIN SMALL LETTER O WITH ACUTE
0xF4	0x00F4	#	LATIN SMALL LETTER O WITH CIRCUMFLEX
0xF5	0x0121	#	LATIN SMALL LETTER G WITH DOT ABOVE
0xF6	0x00F6	#	LATIN SMALL LETTER O WITH DIAERESIS
0xF7	0x00F7	#	DIVISION SIGN
0xF8	0x011D	#	LATIN SMALL LETTER G WITH CIRCUMFLEX
0xF9	0x00F9	#	LATIN SMALL LETTER U WITH GRAVE
0xFA	0x00FA	#	LATIN SMALL LETTER U WITH ACUTE
0xFB	0x00FB	#	LATIN SMALL LETTER U WITH CIRCUMFLEX
0xFC	0x00FC	#	LATIN SMALL LETTER U WITH DIAERESIS
0xFD	0x016D	#	LATIN SMALL LETTER U WITH BREVE
0xFE	0x015D	#	LATIN SMALL LETTER S WITH CIRCUMFLEX
0xFF	0x02D9	#	DOT ABOVE