5
|
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 ------------------------------------------------------------*/
|