comparison spandsp-0.0.3/spandsp-0.0.3/src/t35.c @ 5:f762bf195c4b

import spandsp-0.0.3
author Peter Meerwald <pmeerw@cosy.sbg.ac.at>
date Fri, 25 Jun 2010 16:00:21 +0200
parents
children
comparison
equal deleted inserted replaced
4:26cd8f1ef0b1 5:f762bf195c4b
1 /*
2 * SpanDSP - a series of DSP components for telephony
3 *
4 * t35.c - ITU T.35 FAX non-standard facility processing.
5 *
6 * Written by Steve Underwood <steveu@coppice.org>
7 *
8 * Copyright (C) 2003 Steve Underwood
9 *
10 * All rights reserved.
11 *
12 * This program is free software; you can redistribute it and/or modify
13 * it under the terms of the GNU General Public License version 2, as
14 * published by the Free Software Foundation.
15 *
16 * This program is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 * GNU General Public License for more details.
20 *
21 * You should have received a copy of the GNU General Public License
22 * along with this program; if not, write to the Free Software
23 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
24 *
25 * $Id: t35.c,v 1.20 2006/11/15 14:57:16 steveu Exp $
26 */
27
28 /*
29 * The NSF data tables are adapted from the NSF handling in HylaFAX, which
30 * carries the following copyright notice:
31 *
32 * Created by Dmitry Bely, April 2000
33 * Copyright (c) 1994-1996 Sam Leffler
34 * Copyright (c) 1994-1996 Silicon Graphics, Inc.
35 * HylaFAX is a trademark of Silicon Graphics
36 *
37 * Permission to use, copy, modify, distribute, and sell this software and
38 * its documentation for any purpose is hereby granted without fee, provided
39 * that (i) the above copyright notices and this permission notice appear in
40 * all copies of the software and related documentation, and (ii) the names of
41 * Sam Leffler and Silicon Graphics may not be used in any advertising or
42 * publicity relating to the software without the specific, prior written
43 * permission of Sam Leffler and Silicon Graphics.
44 *
45 * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND,
46 * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY
47 * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.
48 *
49 * IN NO EVENT SHALL SAM LEFFLER OR SILICON GRAPHICS BE LIABLE FOR
50 * ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND,
51 * OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
52 * WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF
53 * LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
54 * OF THIS SOFTWARE.
55 */
56
57 /*! \file */
58
59 #ifdef HAVE_CONFIG_H
60 #include <config.h>
61 #endif
62
63 #include <inttypes.h>
64 #include <ctype.h>
65 #include <string.h>
66
67 #include "spandsp/telephony.h"
68 #include "spandsp/bit_operations.h"
69 #include "spandsp/t35.h"
70
71 typedef struct
72 {
73 int model_id_size;
74 const char *model_id;
75 const char *model_name;
76 } model_data_t;
77
78 typedef struct
79 {
80 const char *vendor_id;
81 int vendor_id_len;
82 const char *vendor_name;
83 int inverse_station_id_order;
84 const model_data_t *known_models;
85 } nsf_data_t;
86
87 const char *t35_country_codes[256] =
88 {
89 "Japan", /* 0x00 */
90 "Albania",
91 "Algeria",
92 "American Samoa",
93 "Germany",
94 "Anguilla",
95 "Antigua and Barbuda",
96 "Argentina",
97 "Ascension (see S. Helena)",
98 "Australia",
99 "Austria",
100 "Bahamas",
101 "Bahrain",
102 "Bangladesh",
103 "Barbados",
104 "Belgium",
105 "Belize",
106 "Benin (Republic of)",
107 "Bermudas",
108 "Bhutan (Kingdom of)",
109 "Bolivia",
110 "Botswana",
111 "Brazil",
112 "British Antarctic Territory",
113 "British Indian Ocean Territory",
114 "British Virgin Islands",
115 "Brunei Darussalam",
116 "Bulgaria",
117 "Myanmar (Union of)",
118 "Burundi",
119 "Byelorussia",
120 "Cameroon",
121 "Canada", /* 0x20 */
122 "Cape Verde",
123 "Cayman Islands",
124 "Central African Republic",
125 "Chad",
126 "Chile",
127 "China",
128 "Colombia",
129 "Comoros",
130 "Congo",
131 "Cook Islands",
132 "Costa Rica",
133 "Cuba",
134 "Cyprus",
135 "Czech and Slovak Federal Republic",
136 "Cambodia",
137 "Democratic People's Republic of Korea",
138 "Denmark",
139 "Djibouti",
140 "Dominican Republic",
141 "Dominica",
142 "Ecuador",
143 "Egypt",
144 "El Salvador",
145 "Equatorial Guinea",
146 "Ethiopia",
147 "Falkland Islands",
148 "Fiji",
149 "Finland",
150 "France",
151 "French Polynesia",
152 "French Southern and Antarctic Lands",
153 "Gabon", /* 0x40 */
154 "Gambia",
155 "Germany (Federal Republic of)",
156 "Angola",
157 "Ghana",
158 "Gibraltar",
159 "Greece",
160 "Grenada",
161 "Guam",
162 "Guatemala",
163 "Guernsey",
164 "Guinea",
165 "Guinea-Bissau",
166 "Guayana",
167 "Haiti",
168 "Honduras",
169 "Hong Kong",
170 "Hungary (Republic of)",
171 "Iceland",
172 "India",
173 "Indonesia",
174 "Iran (Islamic Republic of)",
175 "Iraq",
176 "Ireland",
177 "Israel",
178 "Italy",
179 "Cote d'Ivoire",
180 "Jamaica",
181 "Afghanistan",
182 "Jersey",
183 "Jordan",
184 "Kenya",
185 "Kiribati", /* 0x60 */
186 "Korea (Republic of)",
187 "Kuwait",
188 "Lao (People's Democratic Republic)",
189 "Lebanon",
190 "Lesotho",
191 "Liberia",
192 "Libya",
193 "Liechtenstein",
194 "Luxembourg",
195 "Macau",
196 "Madagascar",
197 "Malaysia",
198 "Malawi",
199 "Maldives",
200 "Mali",
201 "Malta",
202 "Mauritania",
203 "Mauritius",
204 "Mexico",
205 "Monaco",
206 "Mongolia",
207 "Montserrat",
208 "Morocco",
209 "Mozambique",
210 "Nauru",
211 "Nepal",
212 "Netherlands",
213 "Netherlands Antilles",
214 "New Caledonia",
215 "New Zealand",
216 "Nicaragua",
217 "Niger", /* 0x80 */
218 "Nigeria",
219 "Norway",
220 "Oman",
221 "Pakistan",
222 "Panama",
223 "Papua New Guinea",
224 "Paraguay",
225 "Peru",
226 "Philippines",
227 "Poland (Republic of)",
228 "Portugal",
229 "Puerto Rico",
230 "Qatar",
231 "Romania",
232 "Rwanda",
233 "Saint Kitts and Nevis",
234 "Saint Croix",
235 "Saint Helena and Ascension",
236 "Saint Lucia",
237 "San Marino",
238 "Saint Thomas",
239 "Sao Tome and Principe",
240 "Saint Vincent and the Grenadines",
241 "Saudi Arabia",
242 "Senegal",
243 "Seychelles",
244 "Sierra Leone",
245 "Singapore",
246 "Solomon Islands",
247 "Somalia",
248 "South Africa",
249 "Spain", /* 0xA0 */
250 "Sri Lanka",
251 "Sudan",
252 "Suriname",
253 "Swaziland",
254 "Sweden",
255 "Switzerland",
256 "Syria",
257 "Tanzania",
258 "Thailand",
259 "Togo",
260 "Tonga",
261 "Trinidad and Tobago",
262 "Tunisia",
263 "Turkey",
264 "Turks and Caicos Islands",
265 "Tuvalu",
266 "Uganda",
267 "Ukraine",
268 "United Arab Emirates",
269 "United Kingdom",
270 "United States",
271 "Burkina Faso",
272 "Uruguay",
273 "U.S.S.R.",
274 "Vanuatu",
275 "Vatican City State",
276 "Venezuela",
277 "Viet Nam",
278 "Wallis and Futuna",
279 "Western Samoa",
280 "Yemen (Republic of)",
281 "Yemen (Republic of)", /* 0xC0 */
282 "Yugoslavia",
283 "Zaire",
284 "Zambia",
285 "Zimbabwe"
286 };
287
288 static const model_data_t Canon[] =
289 {
290 {5, "\x80\x00\x80\x48\x00", "Faxphone B640"},
291 {5, "\x80\x00\x80\x49\x10", "Fax B100"},
292 {5, "\x80\x00\x8A\x49\x10", "Laser Class 9000 Series"},
293 {0, NULL, NULL}
294 };
295
296 static const model_data_t Brother[] =
297 {
298 {9, "\x55\x55\x00\x88\x90\x80\x5F\x00\x15\x51", "Intellifax 770"},
299 {9, "\x55\x55\x00\x80\xB0\x80\x00\x00\x59\xD4", "Personal fax 190"},
300 {9, "\x55\x55\x00\x8C\x90\x80\xF0\x02\x20", "MFC-8600"},
301 {0, NULL, NULL}
302 };
303
304 static const model_data_t Panasonic0E[] =
305 {
306 {10, "\x00\x00\x00\x96\x0F\x01\x02\x00\x10\x05\x02\x95\xC8\x08\x01\x49\x02\x41\x53\x54\x47", "KX-F90"},
307 {10, "\x00\x00\x00\x96\x0F\x01\x03\x00\x10\x05\x02\x95\xC8\x08\x01\x49\x02 \x03", "KX-F230 or KX-FT21 or ..."},
308 {10, "\x00\x00\x00\x16\x0F\x01\x03\x00\x10\x05\x02\x95\xC8\x08", "KX-F780"},
309 {10, "\x00\x00\x00\x16\x0F\x01\x03\x00\x10\x00\x02\x95\x80\x08\x75\xB5", "KX-M260"},
310 {10, "\x00\x00\x00\x16\x0F\x01\x02\x00\x10\x05\x02\x85\xC8\x08\xAD", "KX-F2050BS"},
311 {0, NULL, NULL}
312 };
313
314 static const model_data_t Panasonic79[] =
315 {
316 {10, "\x00\x00\x00\x02\x0F\x09\x12\x00\x10\x05\x02\x95\xC8\x88\x80\x80\x01", "UF-S10"},
317 {10, "\x00\x00\x00\x16\x7F\x09\x13\x00\x10\x05\x16\x8D\xC0\xD0\xF8\x80\x01", "/Siemens Fax 940"},
318 {10, "\x00\x00\x00\x16\x0F\x09\x13\x00\x10\x05\x06\x8D\xC0\x50\xCB", "Panafax UF-321"},
319 {0, NULL, NULL}
320 };
321
322 static const model_data_t Ricoh[] =
323 {
324 {10, "\x00\x00\x00\x12\x10\x0D\x02\x00\x50\x00\x2A\xB8\x2C", "/Nashuatec P394"},
325 {0, NULL, NULL}
326 };
327
328 static const model_data_t Samsung16[] =
329 {
330 {4, "\x00\x00\xA4\x01", "M545 6800"},
331 {0, NULL, NULL}
332 };
333
334 static const model_data_t Samsung8C[] =
335 {
336 {4, "\x00\x00\x01\x00", "SF-2010"},
337 {0, NULL, NULL}
338 };
339
340 static const model_data_t SamsungA2[] =
341 {
342 {4, "\x00\x00\x80\x00", "FX-4000"},
343 {0, NULL, NULL}
344 };
345
346 static const model_data_t Sanyo[] =
347 {
348 {10, "\x00\x00\x10\xB1\x04\x04\x04\x04\x04\x04\x04\x04\x04\x04\x04\x04\x04\x04\x04\x04\x04\x04\x04\x04\x04\x04\x04\x04\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x41\x26\xFF\xFF\x00\x00\x85\xA1", "SFX-107"},
349 {10, "\x00\x00\x00\xB1\x12\xF2\x62\xB4\x82\x0A\xF2\x2A\x12\xD2\xA2\x04\x04\x04\x04\x04\x04\x04\x04\x04\x04\x04\x04\x04\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x41\x4E\xFF\xFF\x00\x00", "MFP-510"},
350 {0, NULL, NULL}
351 };
352
353 static const model_data_t HP[] =
354 {
355 {5, "\x20\x00\x45\x00\x0C\x04\x70\xCD\x4F\x00\x7F\x49", "LaserJet 3150"},
356 {5, "\x40\x80\x84\x01\xF0\x6A", "OfficeJet"},
357 {5, "\xC0\x00\x00\x00\x00", "OfficeJet 500"},
358 {5, "\xC0\x00\x00\x00\x00\x8B", "Fax-920"},
359 {0, NULL, NULL}
360 };
361
362 static const model_data_t Sharp[] =
363 {
364 {32, "\x00\xCE\xB8\x80\x80\x11\x85\x0D\xDD\x00\x00\xDD\xDD\x00\x00\xDD\xDD\x00\x00\x00\x00\x00\x00\x00\x00\xED\x22\xB0\x00\x00\x90\x00", "Sharp F0-10"},
365 {33, "\x00\xCE\xB8\x80\x80\x11\x85\x0D\xDD\x00\x00\xDD\xDD\x00\x00\xDD\xDD\x00\x00\x00\x00\x00\x00\x00\x00\xED\x22\xB0\x00\x00\x90\x00\x8C", "Sharp UX-460"},
366 {33, "\x00\x4E\xB8\x80\x80\x11\x84\x0D\xDD\x00\x00\xDD\xDD\x00\x00\xDD\xDD\x00\x00\x00\x00\x00\x00\x00\x00\xED\x22\xB0\x00\x00\x90\x00\xAD", "Sharp UX-177"},
367 {33, "\x00\xCE\xB8\x00\x84\x0D\xDD\x00\x00\xDD\xDD\x00\x00\xDD\xDD\xDD\xDD\xDD\x02\x05\x28\x02\x22\x43\x29\xED\x23\x90\x00\x00\x90\x01\x00", "Sharp FO-4810"},
368 {0, NULL, NULL}
369 };
370
371 static const model_data_t Xerox[] =
372 {
373 {10, "\x00\x08\x2D\x43\x57\x50\x61\x75\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x01\x1A\x02\x02\x10\x01\x82\x01\x30\x34", "635 Workcenter"},
374 {0, NULL, NULL}
375 };
376
377 static const model_data_t XeroxDA[] =
378 {
379 {4, "\x00\x00\xC0\x00", "Workcentre Pro 580"},
380 {0, NULL, NULL}
381 };
382
383 static const model_data_t Lexmark[] =
384 {
385 {4, "\x00\x80\xA0\x00", "X4270"},
386 {0, NULL, NULL}
387 };
388
389 static const model_data_t JetFax[] =
390 {
391 {6, "\x01\x00\x45\x00\x0D\x7F", "M910e"},
392 {0, NULL, NULL}
393 };
394
395 static const model_data_t PitneyBowes[] =
396 {
397 {6, "\x79\x91\xB1\xB8\x7A\xD8", "9550"},
398 {0, NULL, NULL}
399 };
400
401 static const model_data_t Dialogic[] =
402 {
403 {8, "\x56\x8B\x06\x55\x00\x15\x00\x00", "VFX/40ESC"},
404 {0, NULL, NULL}
405 };
406
407 static const model_data_t Muratec45[] =
408 {
409 {10, "\xF4\x91\xFF\xFF\xFF\x42\x2A\xBC\x01\x57", "M4700"},
410 {0, NULL, NULL}
411 };
412
413 /* Muratec uses unregistered Japan code "00 00 48" */
414 static const model_data_t Muratec48[] =
415 {
416 {3, "\x53\x53\x61", "M620"},
417 {0, NULL, NULL}
418 };
419
420 /*
421 * Country code first byte, then manufacturer is last two bytes. See T.35.
422 * Apparently Germany issued some manufacturer codes before the two-byte
423 * standard was accepted, and so some few German manufacturers are
424 * identified by a single manufacturer byte.
425 *
426 * T.30 5.3.6.2.7 (2003) states that the NSF FIF is transmitted
427 * in MSB2LSB order. Revisions of T.30 prior to 2003 did not
428 * contain explicit specification as to the transmit bit order.
429 * (Although it did otherwise state that all HDLC frame data should
430 * be in MSB order except as noted.) Because CSI, TSI, and other
431 * prologue frames were in LSB order by way of an exception to the
432 * general rule (T.30 5.3.6.2.4-11) many manufacturers assumed that
433 * NSF should also be in LSB order. Consequently there will be
434 * some country-code "masquerading" as a terminal may use the
435 * proper country-code, but with an inverted bit order.
436 *
437 * Thus, country code x61 (Korea) turns into x86 (Papua New Guinea),
438 * code xB5 (USA) turns into xAD (Tunisia), code x26 (China) turns
439 * into x64 (Lebanon), code x04 (Germany) turns into x20 (Canada),
440 * and code x3D (France) turns into xBC (Vietnam).
441 *
442 * For the most part it should be safe to identify a manufacturer
443 * both with the MSB and LSB ordered bits, as the "masqueraded" country
444 * is likely to not be actively assigning T.38 manufacturer codes.
445 * However, some manufacturers (e.g. Microsoft) may use MSB for the
446 * country code and LSB for the rest of the NSF, and so basically this
447 * table must be verified and corrected against actual real-world
448 * results.
449 */
450 static const nsf_data_t known_nsf[] =
451 {
452 /* Japan */
453 {"\x00\x00\x00", 3, "unknown - indeterminate", TRUE, NULL},
454 {"\x00\x00\x01", 3, "Anjitsu", FALSE, NULL},
455 {"\x00\x00\x02", 3, "Nippon Telephone", FALSE, NULL},
456 {"\x00\x00\x05", 3, "Mitsuba Electric", FALSE, NULL},
457 {"\x00\x00\x06", 3, "Master Net", FALSE, NULL},
458 {"\x00\x00\x09", 3, "Xerox/Toshiba", TRUE, Xerox},
459 {"\x00\x00\x0A", 3, "Kokusai", FALSE, NULL},
460 {"\x00\x00\x0D", 3, "Logic System International", FALSE, NULL},
461 {"\x00\x00\x0E", 3, "Panasonic", FALSE, Panasonic0E},
462 {"\x00\x00\x11", 3, "Canon", FALSE, Canon},
463 {"\x00\x00\x15", 3, "Toyotsushen Machinery", FALSE, NULL},
464 {"\x00\x00\x16", 3, "System House Mind", FALSE, NULL},
465 {"\x00\x00\x19", 3, "Xerox", TRUE, NULL},
466 {"\x00\x00\x1D", 3, "Hitachi Software", FALSE, NULL},
467 {"\x00\x00\x21", 3, "Oki Electric/Lanier", TRUE, NULL},
468 {"\x00\x00\x25", 3, "Ricoh", TRUE, Ricoh},
469 {"\x00\x00\x26", 3, "Konica", FALSE, NULL},
470 {"\x00\x00\x29", 3, "Japan Wireless", FALSE, NULL},
471 {"\x00\x00\x2D", 3, "Sony", FALSE, NULL},
472 {"\x00\x00\x31", 3, "Sharp/Olivetti", FALSE, Sharp},
473 {"\x00\x00\x35", 3, "Kogyu", FALSE, NULL},
474 {"\x00\x00\x36", 3, "Japan Telecom", FALSE, NULL},
475 {"\x00\x00\x3D", 3, "IBM Japan", FALSE, NULL},
476 {"\x00\x00\x39", 3, "Panasonic", FALSE, NULL},
477 {"\x00\x00\x41", 3, "Swasaki Communication", FALSE, NULL},
478 {"\x00\x00\x45", 3, "Muratec", FALSE, Muratec45},
479 {"\x00\x00\x46", 3, "Pheonix", FALSE, NULL},
480 {"\x00\x00\x48", 3, "Muratec", FALSE, Muratec48}, // not registered
481 {"\x00\x00\x49", 3, "Japan Electric", FALSE, NULL},
482 {"\x00\x00\x4D", 3, "Okura Electric", FALSE, NULL},
483 {"\x00\x00\x51", 3, "Sanyo", FALSE, Sanyo},
484 {"\x00\x00\x55", 3, "unknown - Japan 55", FALSE, NULL},
485 {"\x00\x00\x56", 3, "Brother", FALSE, Brother},
486 {"\x00\x00\x59", 3, "Fujitsu", FALSE, NULL},
487 {"\x00\x00\x5D", 3, "Kuoni", FALSE, NULL},
488 {"\x00\x00\x61", 3, "Casio", FALSE, NULL},
489 {"\x00\x00\x65", 3, "Tateishi Electric", FALSE, NULL},
490 {"\x00\x00\x66", 3, "Utax/Mita", TRUE, NULL},
491 {"\x00\x00\x69", 3, "Hitachi Production", FALSE, NULL},
492 {"\x00\x00\x6D", 3, "Hitachi Telecom", FALSE, NULL},
493 {"\x00\x00\x71", 3, "Tamura Electric Works", FALSE, NULL},
494 {"\x00\x00\x75", 3, "Tokyo Electric Corp.", FALSE, NULL},
495 {"\x00\x00\x76", 3, "Advance", FALSE, NULL},
496 {"\x00\x00\x79", 3, "Panasonic", FALSE, Panasonic79},
497 {"\x00\x00\x7D", 3, "Seiko", FALSE, NULL},
498 {"\x00\x08\x00", 3, "Daiko", FALSE, NULL},
499 {"\x00\x10\x00", 3, "Funai Electric", FALSE, NULL},
500 {"\x00\x20\x00", 3, "Eagle System", FALSE, NULL},
501 {"\x00\x30\x00", 3, "Nippon Business Systems", FALSE, NULL},
502 {"\x00\x40\x00", 3, "Comtron", FALSE, NULL},
503 {"\x00\x48\x00", 3, "Cosmo Consulting", FALSE, NULL},
504 {"\x00\x50\x00", 3, "Orion Electric", FALSE, NULL},
505 {"\x00\x60\x00", 3, "Nagano Nippon", FALSE, NULL},
506 {"\x00\x70\x00", 3, "Kyocera", FALSE, NULL},
507 {"\x00\x80\x00", 3, "Kanda Networks", FALSE, NULL},
508 {"\x00\x88\x00", 3, "Soft Front", FALSE, NULL},
509 {"\x00\x90\x00", 3, "Arctic", FALSE, NULL},
510 {"\x00\xA0\x00", 3, "Nakushima", FALSE, NULL},
511 {"\x00\xB0\x00", 3, "Minolta", FALSE, NULL},
512 {"\x00\xC0\x00", 3, "Tohoku Pioneer", FALSE, NULL},
513 {"\x00\xD0\x00", 3, "USC", FALSE, NULL},
514 {"\x00\xE0\x00", 3, "Hiboshi", FALSE, NULL},
515 {"\x00\xF0\x00", 3, "Sumitomo Electric", FALSE, NULL},
516
517 /* Germany */
518 {"\x20\x09", 2, "ITK Institut für Telekommunikation GmbH & Co KG", FALSE, NULL},
519 {"\x20\x11", 2, "Dr. Neuhaus Mikroelektronik", FALSE, NULL},
520 {"\x20\x21", 2, "ITO Communication", FALSE, NULL},
521 {"\x20\x31", 2, "mbp Kommunikationssysteme GmbH", FALSE, NULL},
522 {"\x20\x41", 2, "Siemens", FALSE, NULL},
523 {"\x20\x42", 2, "Deutsche Telekom AG", FALSE, NULL},
524 {"\x20\x51", 2, "mps Software", FALSE, NULL},
525 {"\x20\x61", 2, "Hauni Elektronik", FALSE, NULL},
526 {"\x20\x71", 2, "Digitronic computersysteme gmbh", FALSE, NULL},
527 {"\x20\x81\x00", 3, "Innovaphone GmbH", FALSE, NULL},
528 {"\x20\x81\x40", 3, "TEDAS Gesellschaft für Telekommunikations-, Daten- und Audiosysteme mbH", FALSE, NULL},
529 {"\x20\x81\x80", 3, "AVM Audiovisuelles Marketing und Computersysteme GmbH", FALSE, NULL},
530 {"\x20\x81\xC0", 3, "EICON Technology Research GmbH", FALSE, NULL},
531 {"\x20\xB1", 2, "Schneider Rundfunkwerke AG", FALSE, NULL},
532 {"\x20\xC2", 2, "Deutsche Telekom AG", FALSE, NULL},
533 {"\x20\xD1", 2, "Ferrari electronik GmbH", FALSE, NULL},
534 {"\x20\xF1", 2, "DeTeWe - Deutsche Telephonwerke AG & Co", FALSE, NULL},
535 {"\x20\xFF", 2, "Germany Regional Code", FALSE, NULL},
536
537 /* China */
538 {"\x64\x00\x00", 3, "unknown - China 00 00", FALSE, NULL},
539 {"\x64\x01\x00", 3, "unknown - China 01 00", FALSE, NULL},
540 {"\x64\x01\x01", 3, "unknown - China 01 01", FALSE, NULL},
541 {"\x64\x01\x02", 3, "unknown - China 01 02", FALSE, NULL},
542
543 /* France */
544 {"\xBC\x53\x01", 3, "Minolta", FALSE, NULL},
545
546 /* Korea */
547 {"\x86\x00\x02", 3, "unknown - Korea 02", FALSE, NULL},
548 {"\x86\x00\x06", 3, "unknown - Korea 06", FALSE, NULL},
549 {"\x86\x00\x08", 3, "unknown - Korea 08", FALSE, NULL},
550 {"\x86\x00\x0A", 3, "unknown - Korea 0A", FALSE, NULL},
551 {"\x86\x00\x0E", 3, "unknown - Korea 0E", FALSE, NULL},
552 {"\x86\x00\x10", 3, "Samsung", FALSE, NULL},
553 {"\x86\x00\x11", 3, "unknown - Korea 11", FALSE, NULL},
554 {"\x86\x00\x16", 3, "Samsung", FALSE, Samsung16},
555 {"\x86\x00\x1A", 3, "unknown - Korea 1A", FALSE, NULL},
556 {"\x86\x00\x40", 3, "unknown - Korea 40", FALSE, NULL},
557 {"\x86\x00\x48", 3, "unknown - Korea 48", FALSE, NULL},
558 {"\x86\x00\x52", 3, "unknown - Korea 52", FALSE, NULL},
559 {"\x86\x00\x5A", 3, "unknown - Korea 5A", FALSE, NULL},
560 {"\x86\x00\x5E", 3, "unknown - Korea 5E", FALSE, NULL},
561 {"\x86\x00\x66", 3, "unknown - Korea 66", FALSE, NULL},
562 {"\x86\x00\x6E", 3, "unknown - Korea 6E", FALSE, NULL},
563 {"\x86\x00\x82", 3, "unknown - Korea 82", FALSE, NULL},
564 {"\x86\x00\x88", 3, "unknown - Korea 88", FALSE, NULL},
565 {"\x86\x00\x8A", 3, "unknown - Korea 8A", FALSE, NULL},
566 {"\x86\x00\x8C", 3, "Samsung", FALSE, Samsung8C},
567 {"\x86\x00\x92", 3, "unknown - Korea 92", FALSE, NULL},
568 {"\x86\x00\x98", 3, "Samsung", FALSE, NULL},
569 {"\x86\x00\xA2", 3, "Samsung", FALSE, SamsungA2},
570 {"\x86\x00\xA4", 3, "unknown - Korea A4", FALSE, NULL},
571 {"\x86\x00\xC9", 3, "unknown - Korea C9", FALSE, NULL},
572 {"\x86\x00\xCC", 3, "unknown - Korea CC", FALSE, NULL},
573 {"\x86\x00\xD2", 3, "unknown - Korea D2", FALSE, NULL},
574 {"\x86\x00\xDA", 3, "Xerox", FALSE, XeroxDA},
575 {"\x86\x00\xE2", 3, "unknown - Korea E2", FALSE, NULL},
576 {"\x86\x00\xEC", 3, "unknown - Korea EC", FALSE, NULL},
577 {"\x86\x00\xEE", 3, "unknown - Korea EE", FALSE, NULL},
578
579 /* United Kingdom */
580 {"\xB4\x00\xB0", 3, "DCE", FALSE, NULL},
581 {"\xB4\x00\xB1", 3, "Hasler", FALSE, NULL},
582 {"\xB4\x00\xB2", 3, "Interquad", FALSE, NULL},
583 {"\xB4\x00\xB3", 3, "Comwave", FALSE, NULL},
584 {"\xB4\x00\xB4", 3, "Iconographic", FALSE, NULL},
585 {"\xB4\x00\xB5", 3, "Wordcraft", FALSE, NULL},
586 {"\xB4\x00\xB6", 3, "Acorn", FALSE, NULL},
587
588 /* United States */
589 {"\xAD\x00\x00", 3, "Pitney Bowes", FALSE, PitneyBowes},
590 {"\xAD\x00\x0C", 3, "Dialogic", FALSE, NULL},
591 {"\xAD\x00\x15", 3, "Lexmark", FALSE, Lexmark},
592 {"\xAD\x00\x16", 3, "JetFax", FALSE, JetFax},
593 {"\xAD\x00\x24", 3, "Octel", FALSE, NULL},
594 {"\xAD\x00\x36", 3, "HP", FALSE, HP},
595 {"\xAD\x00\x42", 3, "FaxTalk", FALSE, NULL},
596 {"\xAD\x00\x44", 3, NULL, TRUE, NULL},
597 {"\xAD\x00\x46", 3, "BrookTrout", FALSE, NULL},
598 {"\xAD\x00\x51", 3, "Telogy Networks", FALSE, NULL},
599 {"\xAD\x00\x55", 3, "HylaFAX", FALSE, NULL},
600 {"\xAD\x00\x5C", 3, "IBM", FALSE, NULL},
601 {"\xAD\x00\x98", 3, "unknown - USA 98", TRUE, NULL},
602 {"\xB5\x00\x01", 3, "Picturetel", FALSE, NULL},
603 {"\xB5\x00\x20", 3, "Conexant", FALSE, NULL},
604 {"\xB5\x00\x22", 3, "Comsat", FALSE, NULL},
605 {"\xB5\x00\x24", 3, "Octel", FALSE, NULL},
606 {"\xB5\x00\x26", 3, "ROLM", FALSE, NULL},
607 {"\xB5\x00\x28", 3, "SOFNET", FALSE, NULL},
608 {"\xB5\x00\x29", 3, "TIA TR-29 Committee", FALSE, NULL},
609 {"\xB5\x00\x2A", 3, "STF Tech", FALSE, NULL},
610 {"\xB5\x00\x2C", 3, "HKB", FALSE, NULL},
611 {"\xB5\x00\x2E", 3, "Delrina", FALSE, NULL},
612 {"\xB5\x00\x30", 3, "Dialogic", FALSE, NULL},
613 {"\xB5\x00\x32", 3, "Applied Synergy", FALSE, NULL},
614 {"\xB5\x00\x34", 3, "Syncro Development", FALSE, NULL},
615 {"\xB5\x00\x36", 3, "Genoa", FALSE, NULL},
616 {"\xB5\x00\x38", 3, "Texas Instruments", FALSE, NULL},
617 {"\xB5\x00\x3A", 3, "IBM", FALSE, NULL},
618 {"\xB5\x00\x3C", 3, "ViaSat", FALSE, NULL},
619 {"\xB5\x00\x3E", 3, "Ericsson", FALSE, NULL},
620 {"\xB5\x00\x42", 3, "Bogosian", FALSE, NULL},
621 {"\xB5\x00\x44", 3, "Adobe", FALSE, NULL},
622 {"\xB5\x00\x46", 3, "Fremont Communications", FALSE, NULL},
623 {"\xB5\x00\x48", 3, "Hayes", FALSE, NULL},
624 {"\xB5\x00\x4A", 3, "Lucent", FALSE, NULL},
625 {"\xB5\x00\x4C", 3, "Data Race", FALSE, NULL},
626 {"\xB5\x00\x4E", 3, "TRW", FALSE, NULL},
627 {"\xB5\x00\x52", 3, "Audiofax", FALSE, NULL},
628 {"\xB5\x00\x54", 3, "Computer Automation", FALSE, NULL},
629 {"\xB5\x00\x56", 3, "Serca", FALSE, NULL},
630 {"\xB5\x00\x58", 3, "Octocom", FALSE, NULL},
631 {"\xB5\x00\x5C", 3, "Power Solutions", FALSE, NULL},
632 {"\xB5\x00\x5A", 3, "Digital Sound", FALSE, NULL},
633 {"\xB5\x00\x5E", 3, "Pacific Data", FALSE, NULL},
634 {"\xB5\x00\x60", 3, "Commetrex", FALSE, NULL},
635 {"\xB5\x00\x62", 3, "BrookTrout", FALSE, NULL},
636 {"\xB5\x00\x64", 3, "Gammalink", FALSE, NULL},
637 {"\xB5\x00\x66", 3, "Castelle", FALSE, NULL},
638 {"\xB5\x00\x68", 3, "Hybrid Fax", FALSE, NULL},
639 {"\xB5\x00\x6A", 3, "Omnifax", FALSE, NULL},
640 {"\xB5\x00\x6C", 3, "HP", FALSE, NULL},
641 {"\xB5\x00\x6E", 3, "Microsoft", FALSE, NULL},
642 {"\xB5\x00\x72", 3, "Speaking Devices", FALSE, NULL},
643 {"\xB5\x00\x74", 3, "Compaq", FALSE, NULL},
644 /*
645 {"\xB5\x00\x76", 3, "Trust - Cryptek", FALSE, NULL}, // collision with Microsoft
646 */
647 {"\xB5\x00\x76", 3, "Microsoft", FALSE, NULL}, // uses LSB for country but MSB for manufacturer
648 {"\xB5\x00\x78", 3, "Cylink", FALSE, NULL},
649 {"\xB5\x00\x7A", 3, "Pitney Bowes", FALSE, NULL},
650 {"\xB5\x00\x7C", 3, "Digiboard", FALSE, NULL},
651 {"\xB5\x00\x7E", 3, "Codex", FALSE, NULL},
652 {"\xB5\x00\x82", 3, "Wang Labs", FALSE, NULL},
653 {"\xB5\x00\x84", 3, "Netexpress Communications", FALSE, NULL},
654 {"\xB5\x00\x86", 3, "Cable-Sat", FALSE, NULL},
655 {"\xB5\x00\x88", 3, "MFPA", FALSE, NULL},
656 {"\xB5\x00\x8A", 3, "Telogy Networks", FALSE, NULL},
657 {"\xB5\x00\x8E", 3, "Telecom Multimedia Systems", FALSE, NULL},
658 {"\xB5\x00\x8C", 3, "AT&T", FALSE, NULL},
659 {"\xB5\x00\x92", 3, "Nuera", FALSE, NULL},
660 {"\xB5\x00\x94", 3, "K56flex", FALSE, NULL},
661 {"\xB5\x00\x96", 3, "MiBridge", FALSE, NULL},
662 {"\xB5\x00\x98", 3, "Xerox", FALSE, NULL},
663 {"\xB5\x00\x9A", 3, "Fujitsu", FALSE, NULL},
664 {"\xB5\x00\x9B", 3, "Fujitsu", FALSE, NULL},
665 {"\xB5\x00\x9C", 3, "Natural Microsystems", FALSE, NULL},
666 {"\xB5\x00\x9E", 3, "CopyTele", FALSE, NULL},
667 {"\xB5\x00\xA2", 3, "Murata", FALSE, NULL},
668 {"\xB5\x00\xA4", 3, "Lanier", FALSE, NULL},
669 {"\xB5\x00\xA6", 3, "Qualcomm", FALSE, NULL},
670 {"\xB5\x00\xAA", 3, "HylaFAX", FALSE, NULL}, // we did it backwards for a while
671 {NULL, 0, NULL, FALSE, NULL}
672 };
673
674 #if 0
675 void nsf_find_station_id(int reverse_order)
676 {
677 const char *id = NULL;
678 int idSize = 0;
679 const char *maxId = NULL;
680 int maxIdSize = 0;
681 const char *p;
682
683 /* Trying to find the longest printable ASCII sequence */
684 for (p = (const char *) nsf + T35_VENDOR_ID_LEN, *end = p + nsf.length();
685 p < end;
686 p++)
687 {
688 if (isprint(*p))
689 {
690 if (!idSize++)
691 id = p;
692 if (idSize > maxIdSize)
693 {
694 max_id = id;
695 max_id_size = idSize;
696 }
697 }
698 else
699 {
700 id = NULL;
701 id_size = 0;
702 }
703 }
704
705 /* Minimum acceptable id length */
706 const int MinIdSize = 4;
707
708 if (maxIdSize >= min_id_size)
709 {
710 stationId.resize(0);
711 const char *p;
712 int dir;
713
714 if (reverseOrder)
715 {
716 p = maxId + maxIdSize - 1;
717 dir = -1;
718 }
719 else
720 {
721 p = maxId;
722 dir = 1;
723 }
724 for (int i = 0; i < maxIdSize; i++)
725 {
726 stationId.append(*p);
727 p += dir;
728 }
729 station_id_decoded = TRUE;
730 }
731 }
732 /*- End of function --------------------------------------------------------*/
733 #endif
734
735 int t35_decode(const uint8_t *msg, int len, const char **country, const char **vendor, const char **model)
736 {
737 int vendor_decoded;
738 const nsf_data_t *p;
739 const model_data_t *pp;
740
741 vendor_decoded = FALSE;
742 if (country)
743 *country = NULL;
744 if (vendor)
745 *vendor = NULL;
746 if (model)
747 *model = NULL;
748 if (country)
749 {
750 /* We need to apply realism over accuracy, though it blocks out some countries.
751 It is very rare to find a machine from any country but the following:
752
753 Japan 0x00 (no confusion)
754 Germany 0x04 (0x20) (Canada/Germany confusion)
755 China 0x26 (0x64) (China/Lebanon confusion)
756 Korea 0x61 (0x86) (Korea/Papua New Guinea confusion)
757 UK 0xB4 (0x2D) (UK/Cyprus confusion)
758 USA 0xB5 (0xAD) (USA/Tunisia confusion)
759 France 0x3D (0xBC) (France/Vietnam confusion)
760
761 If we force the most likely of the two possible countries (forward or bit reversed),
762 the only mixup with any realistic probability is the Canada/Germany confusion. We
763 will just live with this, and force the more likely countries. */
764 switch (msg[0])
765 {
766 case 0x20:
767 /* Force Germany */
768 *country = t35_country_codes[0x04];
769 break;
770 case 0x64:
771 /* Force China */
772 *country = t35_country_codes[0x26];
773 break;
774 case 0x86:
775 /* Force Korea */
776 *country = t35_country_codes[0x61];
777 break;
778 case 0x2D:
779 /* Force UK */
780 *country = t35_country_codes[0xB4];
781 break;
782 case 0xAD:
783 /* Force USA */
784 *country = t35_country_codes[0xB5];
785 break;
786 case 0xBC:
787 /* Force France */
788 *country = t35_country_codes[0x3D];
789 break;
790 default:
791 /* Try the country code at face value, then bit reversed */
792 if (t35_country_codes[msg[0]])
793 *country = t35_country_codes[msg[0]];
794 else if (t35_country_codes[bit_reverse8(msg[0])])
795 *country = t35_country_codes[bit_reverse8(msg[0])];
796 break;
797 }
798 }
799 for (p = known_nsf; p->vendor_id; p++)
800 {
801 if (len >= p->vendor_id_len
802 &&
803 memcmp(p->vendor_id, msg, p->vendor_id_len) == 0)
804 {
805 if (p->vendor_name && vendor)
806 *vendor = p->vendor_name;
807 if (p->known_models && model)
808 {
809 for (pp = p->known_models; pp->model_id; pp++)
810 {
811 if (len == p->vendor_id_len + pp->model_id_size
812 &&
813 memcmp(pp->model_id, &msg[p->vendor_id_len], pp->model_id_size) == 0)
814 {
815 *model = pp->model_name;
816 break;
817 }
818 }
819 }
820 #if 0
821 findStationId(p->inverse_station_id_order);
822 #endif
823 vendor_decoded = TRUE;
824 break;
825 }
826 }
827 #if 0
828 if (!vendor_found())
829 find_station_id(0);
830 #endif
831 return vendor_decoded;
832 }
833 /*- End of function --------------------------------------------------------*/
834 /*- End of file ------------------------------------------------------------*/

Repositories maintained by Peter Meerwald, pmeerw@pmeerw.net.