comparison spandsp-0.0.6pre17/src/t35.c @ 4:26cd8f1ef0b1

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

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