Mercurial > hg > audiostuff
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 ------------------------------------------------------------*/ |