OSDN Git Service

2013.10.24
[uclinux-h8/uClinux-dist.git] / user / mgetty / hyla_nsf.c
1 /* $Id: hyla_nsf.c,v 4.8 2010/06/05 09:49:37 gert Exp $ */
2 /* 
3  * The tables in this file are taken from the HylaFAX distribution.  Thus,
4  * the Hylafax copyright (below) applies, not the mgetty copyright (GPL).
5  *
6  * This file does not exist in the original HylaFAX distribution.
7  * Created by Dmitry Bely, April 2000
8  */
9 /*
10  * Copyright (c) 1994-1996 Sam Leffler
11  * Copyright (c) 1994-1996 Silicon Graphics, Inc.
12  * HylaFAX is a trademark of Silicon Graphics
13  *
14  * Permission to use, copy, modify, distribute, and sell this software and 
15  * its documentation for any purpose is hereby granted without fee, provided
16  * that (i) the above copyright notices and this permission notice appear in
17  * all copies of the software and related documentation, and (ii) the names of
18  * Sam Leffler and Silicon Graphics may not be used in any advertising or
19  * publicity relating to the software without the specific, prior written
20  * permission of Sam Leffler and Silicon Graphics.
21  * 
22  * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND, 
23  * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY 
24  * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.  
25  * 
26  * IN NO EVENT SHALL SAM LEFFLER OR SILICON GRAPHICS BE LIABLE FOR
27  * ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND,
28  * OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
29  * WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF 
30  * LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE 
31  * OF THIS SOFTWARE.
32  */
33
34
35 #include <stdio.h>
36 #include <memory.h>
37 #include "mgetty.h"
38 #include "policy.h"
39
40 #ifdef FAX_NSF_PARSER
41
42 typedef char bool;
43 #define true 1
44 #define false 0
45
46 struct ModelData 
47 {
48     const char* modelId;
49     const char* modelName;
50 };
51
52 typedef struct ModelData ModelData;
53
54 struct NSFData {
55     const char* vendorId;
56     unsigned int vendorIdSize;  /* Country & provider code (T.35) */
57     const char* vendorName;
58     bool        inverseStationIdOrder;
59     unsigned int         modelIdPos;
60     unsigned int         modelIdSize;
61     const ModelData* knownModels;
62 };
63
64 typedef struct NSFData NSFData;
65
66 /*
67  * Unless a manufacturer is able to provide detailed specifics
68  * of the construction of their NSF signals the only guaranteed
69  * accurate information that we get from NSF is the manufacturer
70  * (once the bitorder and construction of the first few bytes is
71  * confirmed).  At that point we would ideally be able to identify
72  * the model type, but doing that is often more guesswork than
73  * anything and is more likely to prove wrong than right, depending
74  * on how specific our ModelData typing is.  Any matches as to the
75  * model identification really should be taken with some degree
76  * of scepticism.
77  *
78  * As manufacturers often encode (in plain text) a station identification
79  * in the NSF string it is often useful to look for that.
80  */
81
82 static const ModelData Canon[] =
83 {{"\x80\x00\x80\x48\x00", "Faxphone B640"},
84  {"\x80\x00\x80\x49\x10", "Fax B100"},
85  {"\x80\x00\x8A\x49\x10", "Laser Class 9000 Series"},
86  {"\x80\x00\x8A\x48\x00", "Laser Class 2060"},
87  {NULL}};
88   
89
90 static const ModelData Brother[] =
91 {{"\x55\x55\x00\x88\x90\x80\x5F\x00\x15\x51", "Fax-560/770"},
92  {"\x55\x55\x00\x80\xB0\x80\x00\x00\x59\xD4", "Personal fax 190"},
93  {"\x55\x55\x00\x8C\x90\x80", "MFC-3100C/MFC-8600"},
94  {NULL}};
95
96 static const ModelData Panasonic0E[] =
97 {{"\x00\x00\x00\x96\x0F\x01\x02\x00\x10\x05\x02\x95\xC8\x08\x01\x49\x02\x41\x53\x54\x47", "KX-F90" },
98  {"\x00\x00\x00\x96\x0F\x01\x03\x00\x10\x05\x02\x95\xC8\x08\x01\x49\x02\x03", "KX-F230/KX-FT21" },
99  {"\x00\x00\x00\x16\x0F\x01\x03\x00\x10\x05\x02\x95\xC8\x08",          "KX-F780" },
100  {"\x00\x00\x00\x16\x0F\x01\x03\x00\x10\x00\x02\x95\x80\x08\x75\xB5",  "KX-M260" },
101  {"\x00\x00\x00\x16\x0F\x01\x02\x00\x10\x05\x02\x85\xC8\x08\xAD", "KX-F2050BS" },
102  {NULL}};
103
104 static const ModelData Panasonic79[] =
105 {{"\x00\x00\x00\x02\x0F\x09\x12\x00\x10\x05\x02\x95\xC8\x88\x80\x80\x01", "UF-S10" },
106  {"\x00\x00\x00\x16\x7F\x09\x13\x00\x10\x05\x16\x8D\xC0\xD0\xF8\x80\x01", "/Siemens Fax 940" },
107  {"\x00\x00\x00\x16\x0F\x09\x13\x00\x10\x05\x06\x8D\xC0\x50\xCB", "Panafax UF-321" },
108  {NULL}};
109
110 static const ModelData Ricoh[] =
111 {{"\x00\x00\x00\x12\x10\x0D\x02\x00\x50\x00\x2A\xB8\x2C", "/Nashuatec P394" },
112  {NULL}};
113
114 static const ModelData Samsung16[] =
115 {{"\x00\x00\xA4\x01", "M545 6800" },
116  {NULL}};
117
118 static const ModelData Samsung8C[] =
119 {{"\x00\x00\x01\x00", "SF-2010" },
120  {NULL}};
121
122 static const ModelData SamsungA2[] =
123 {{"\x00\x00\x80\x00", "FX-4000" },
124  {NULL}};
125
126 static const ModelData Sanyo[] =
127 {{"\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" },
128  {"\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" },
129  {NULL}};
130
131 static const ModelData HP[] =
132 {{"\x20\x00\x45\x00\x0C\x04\x70\xCD\x4F\x00\x7F\x49", "LaserJet 3150" },
133  {"\x04\x00\x00\x00\x00", "LaserJet 3030" },    /* gert */
134  {"\x40\x80\x84\x01\xF0\x6A", "OfficeJet" },
135  {"\xC0\x00\x00\x00\x00", "OfficeJet 500" },
136  {"\xC0\x00\x00\x00\x00\x8B", "Fax-920" },
137  {NULL}};
138
139 static const ModelData Sharp[] =
140 {{"\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" },
141  {"\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" },
142  {"\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" },
143  {NULL}};
144
145 static const ModelData Xerox[] =
146 {{"\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" },
147  {"\x00\x08\x0D\x49\xFF\xFF\xFF\xFF\xFF\xFF", "DP85F" },        /* gert */
148  {NULL}};
149
150 static const ModelData XeroxDA[] =
151 {{"\x00\x00\xC0\x00", "Workcentre Pro 580" },
152  {NULL}};
153
154 static const ModelData Lexmark[] =
155 {{"\x00\x80\xA0\x00", "X4270" },
156  {NULL}};
157
158 static const ModelData JetFax[] =
159 {{"\x01\x00\x45\x00\x0D\x7F", "M910e" },
160  {NULL}};
161
162 static const ModelData PitneyBowes[] = 
163 {{"\x79\x91\xB1\xB8\x7A\xD8", "9550" },
164  {NULL}};
165
166 static const ModelData Muratec45[] =
167 {{"\xF4\x91\xFF\xFF\xFF\x42\x2A\xBC\x01\x57", "M4700" },
168  {NULL}};
169
170 static const ModelData Muratec48[] =
171 {{"\x53\x53\x61", "M620" },
172  {NULL}};
173
174 /*
175  * Country code first byte, then manufacturer is last two bytes. See T.35.
176  * Apparently Germany issued some manufacturer codes before the two-byte
177  * standard was accepted, and so some few German manufacturers are
178  * identified by a single manufacturer byte.
179  *
180  * T.30 5.3.6.2.7 (2003) states that the NSF FIF is transmitted
181  * in MSB2LSB order.  Revisions of T.30 prior to 2003 did not 
182  * contain explicit specification as to the transmit bit order.
183  * (Although it did otherwise state that all HDLC frame data should
184  * be in MSB order except as noted.)  Because CSI, TSI, and other
185  * prologue frames were in LSB order by way of an exception to the
186  * general rule (T.30 5.3.6.2.4-11) many manufacturers assumed that
187  * NSF should also be in LSB order.  Consequently there will be
188  * some country-code "masquerading" as a terminal may use the
189  * proper country-code, but with an inverted bit order.
190  *
191  * Thus, country code x61 (Korea) turns into x86 (Papua New Guinea),
192  * code xB5 (USA) turns into xAD (Tunisia), code x26 (China) turns
193  * into x64 (Lebanon), code x04 (Germany) turns into x20 (Canada), 
194  * and code x3D (France) turns into xBC (Vietnam).
195  *
196  * For the most part it should be safe to identify a manufacturer
197  * both with the MSB and LSB ordered bits, as the "masqueraded" country
198  * is likely to not be actively assigning T.35 manufacturer codes.
199  * However, some manufacturers (e.g. Microsoft) may use MSB for the
200  * country code and LSB for the rest of the NSF, and so basically this
201  * table must be verified and corrected against actual real-world
202  * results.
203  */
204 static const NSFData KnownNSF[] =
205 {
206     /* Japan */
207     {"\x00\x00\x00", 3, "unknown - indeterminate", true },
208     {"\x00\x00\x01", 3, "Anjitsu",  false },
209     {"\x00\x00\x02", 3, "Nippon Telephone", false },
210     {"\x00\x00\x05", 3, "Mitsuba Electric", false },
211     {"\x00\x00\x06", 3, "Master Net", false },
212     {"\x00\x00\x09", 3, "Xerox/Toshiba", true, 3, 10, Xerox },
213     {"\x00\x00\x0A", 3, "Kokusai",   false },
214     {"\x00\x00\x0D", 3, "Logic System International", false },
215     {"\x00\x00\x0E", 3, "Panasonic", false, 3,10, Panasonic0E },
216     {"\x00\x00\x11", 3, "Canon",     false, 3, 5, Canon },
217     {"\x00\x00\x15", 3, "Toyotsushen Machinery", false },
218     {"\x00\x00\x16", 3, "System House Mind", false },
219     {"\x00\x00\x19", 3, "Xerox",     true  },
220     {"\x00\x00\x1D", 3, "Hitachi Software", false },
221     {"\x00\x00\x21", 3, "Oki Electric/Lanier", true },
222     {"\x00\x00\x25", 3, "Ricoh",     true,  3,10, Ricoh },
223     {"\x00\x00\x26", 3, "Konica",    false },
224     {"\x00\x00\x29", 3, "Japan Wireless", false },
225     {"\x00\x00\x2D", 3, "Sony",      false },
226     {"\x00\x00\x31", 3, "Sharp/Olivetti", false, 3, 10, Sharp },
227     {"\x00\x00\x35", 3, "Kogyu", false },
228     {"\x00\x00\x36", 3, "Japan Telecom", false },
229     {"\x00\x00\x3D", 3, "IBM Japan", false },
230     {"\x00\x00\x39", 3, "Panasonic", false },
231     {"\x00\x00\x41", 3, "Swasaki Communication", false },
232     {"\x00\x00\x45", 3, "Muratec",   false, 3,10, Muratec45 },
233     {"\x00\x00\x46", 3, "Pheonix",   false },
234     {"\x00\x00\x48", 3, "Muratec",   false, 3,3, Muratec48 },   /* not registered */
235     {"\x00\x00\x49", 3, "Japan Electric", false },
236     {"\x00\x00\x4D", 3, "Okura Electric", false },
237     {"\x00\x00\x51", 3, "Sanyo",     false, 3,10, Sanyo },
238     {"\x00\x00\x55", 3, "unknown - Japan 55", false },
239     {"\x00\x00\x56", 3, "Brother",   false, 3, 6, Brother },
240     {"\x00\x00\x59", 3, "Fujitsu",   false },
241     {"\x00\x00\x5D", 3, "Kuoni",     false },
242     {"\x00\x00\x61", 3, "Casio",     false },
243     {"\x00\x00\x65", 3, "Tateishi Electric", false },
244     {"\x00\x00\x66", 3, "Utax/Mita", true  },
245     {"\x00\x00\x69", 3, "Hitachi Production",   false },
246     {"\x00\x00\x6D", 3, "Hitachi Telecom", false },
247     {"\x00\x00\x71", 3, "Tamura Electric Works", false },
248     {"\x00\x00\x75", 3, "Tokyo Electric Corp.", false },
249     {"\x00\x00\x76", 3, "Advance",   false },
250     {"\x00\x00\x79", 3, "Panasonic", false, 3,10, Panasonic79 },
251     {"\x00\x00\x7D", 3, "Seiko",     false },
252     {"\x00\x08\x00", 3, "Daiko",     false },
253     {"\x00\x10\x00", 3, "Funai Electric", false },
254     {"\x00\x20\x00", 3, "Eagle System", false },
255     {"\x00\x30\x00", 3, "Nippon Business Systems", false },
256     {"\x00\x40\x00", 3, "Comtron",   false },
257     {"\x00\x48\x00", 3, "Cosmo Consulting", false },
258     {"\x00\x50\x00", 3, "Orion Electric", false },
259     {"\x00\x60\x00", 3, "Nagano Nippon", false },
260     {"\x00\x70\x00", 3, "Kyocera",   false },
261     {"\x00\x80\x00", 3, "Kanda Networks", false },
262     {"\x00\x88\x00", 3, "Soft Front", false },
263     {"\x00\x90\x00", 3, "Arctic",    false },
264     {"\x00\xA0\x00", 3, "Nakushima", false },
265     {"\x00\xB0\x00", 3, "Minolta", false },
266     {"\x00\xC0\x00", 3, "Tohoku Pioneer", false },
267     {"\x00\xD0\x00", 3, "USC",       false },
268     {"\x00\xE0\x00", 3, "Hiboshi",   false },
269     {"\x00\xF0\x00", 3, "Sumitomo Electric", false },
270     /* Germany */
271     {"\x20\x09",     2, "ITK Institut fuer Telekommunikation GmbH & Co KG", false },
272     {"\x20\x11",     2, "Dr. Neuhaus Mikroelektronik", false },
273     {"\x20\x21",     2, "ITO Communication", false },
274     {"\x20\x31",     2, "mbp Kommunikationssysteme GmbH", false },
275     {"\x20\x41",     2, "Siemens", false },
276     {"\x20\x42",     2, "Deutsche Telekom AG", false },
277     {"\x20\x51",     2, "mps Software", false },
278     {"\x20\x61",     2, "Hauni Elektronik", false },
279     {"\x20\x71",     2, "Digitronic computersysteme gmbh", false },
280     {"\x20\x81\x00", 3, "Innovaphone GmbH", false },
281     {"\x20\x81\x40", 3, "TEDAS Gesellschaft fuer Telekommunikations-, Daten- und Audiosysteme mbH", false },
282     {"\x20\x81\x80", 3, "AVM Audiovisuelles Marketing und Computersysteme GmbH", false },
283     {"\x20\x81\xC0", 3, "EICON Technology Research GmbH", false },
284     {"\x20\x81\x70", 3, "mgetty+sendfax", false },
285     {"\x20\xB1",     2, "Schneider Rundfunkwerke AG", false },
286     {"\x20\xC2",     2, "Deutsche Telekom AG", false },
287     {"\x20\xD1",     2, "Ferrari electronik GmbH", false },
288     {"\x20\xF1",     2, "DeTeWe - Deutsche Telephonwerke AG & Co", false },
289     {"\x20\xFF",     2, "Germany Regional Code", false },
290     /* China */
291     {"\x64\x00\x00", 3, "unknown - China 00 00", false },
292     {"\x64\x01\x00", 3, "unknown - China 01 00", false },
293     {"\x64\x01\x01", 3, "unknown - China 01 01", false },
294     {"\x64\x01\x02", 3, "unknown - China 01 02", false },
295     /* France */
296     {"\xBC\x53\x01", 3, "Minolta",   false },
297     /* Korea */
298     {"\x61\x00\x7A", 3, "Xerox", false },
299     {"\x86\x00\x02", 3, "unknown - Korea 02", false },
300     {"\x86\x00\x06", 3, "unknown - Korea 06", false },
301     {"\x86\x00\x08", 3, "unknown - Korea 08", false },
302     {"\x86\x00\x0A", 3, "unknown - Korea 0A", false },
303     {"\x86\x00\x0E", 3, "unknown - Korea 0E", false },
304     {"\x86\x00\x10", 3, "Samsung",   false },
305     {"\x86\x00\x11", 3, "unknown - Korea 11" },
306     {"\x86\x00\x16", 3, "Samsung", false, 3, 4, Samsung16 },
307     {"\x86\x00\x1A", 3, "unknown - Korea 1A", false },
308     {"\x86\x00\x40", 3, "unknown - Korea 40", false },
309     {"\x86\x00\x48", 3, "Samsung/Dell", false },
310     {"\x86\x00\x52", 3, "unknown - Korea 52", false },
311     {"\x86\x00\x5A", 3, "Samsung", false },
312     {"\x86\x00\x5E", 3, "Xerox", false },
313     {"\x86\x00\x66", 3, "unknown - Korea 66", false },
314     {"\x86\x00\x6E", 3, "unknown - Korea 6E", false },
315     {"\x86\x00\x82", 3, "unknown - Korea 82", false },
316     {"\x86\x00\x88", 3, "Ricoh", false },
317     {"\x86\x00\x8A", 3, "unknown - Korea 8A", false },
318     {"\x86\x00\x8C", 3, "Samsung", false, 3, 4, Samsung8C },
319     {"\x86\x00\x92", 3, "unknown - Korea 92", false },
320     {"\x86\x00\x98", 3, "Samsung",   false },
321     {"\x86\x00\xA2", 3, "Samsung", false, 3, 4, SamsungA2 },
322     {"\x86\x00\xA4", 3, "unknown - Korea A4", false },
323     {"\x86\x00\xC2", 3, "Samsung", false },
324     {"\x86\x00\xC9", 3, "unknown - Korea C9", false },
325     {"\x86\x00\xCC", 3, "unknown - Korea CC", false },
326     {"\x86\x00\xD2", 3, "unknown - Korea D2", false },
327     {"\x86\x00\xDA", 3, "Xerox", false, 3, 4, XeroxDA },
328     {"\x86\x00\xE2", 3, "unknown - Korea E2", false },
329     {"\x86\x00\xEC", 3, "unknown - Korea EC", false },
330     {"\x86\x00\xEE", 3, "unknown - Korea EE", false },
331     /* United Kingdom */
332     {"\xB4\x00\xB0", 3, "DCE",       false },
333     {"\xB4\x00\xB1", 3, "Hasler",    false },
334     {"\xB4\x00\xB2", 3, "Interquad", false },
335     {"\xB4\x00\xB3", 3, "Comwave",   false },
336     {"\xB4\x00\xB4", 3, "Iconographic", false },
337     {"\xB4\x00\xB5", 3, "Wordcraft", false },
338     {"\xB4\x00\xB6", 3, "Acorn",     false },
339     /* United States */
340     {"\xAD\x00\x00", 3, "Pitney Bowes", false, 3, 6, PitneyBowes },
341     {"\xAD\x00\x0C", 3, "Dialogic",  false },
342     {"\xAD\x00\x15", 3, "Lexmark",   false, 3, 4, Lexmark },
343     {"\xAD\x00\x16", 3, "JetFax",    false, 3, 6, JetFax },
344     {"\xAD\x00\x24", 3, "Octel",     false },
345     {"\xAD\x00\x36", 3, "HP",        false, 3, 5, HP },
346     {"\xAD\x00\x42", 3, "FaxTalk",   false },
347     {"\xAD\x00\x44", 3, NULL,        true },
348     {"\xAD\x00\x46", 3, "BrookTrout", false },
349     {"\xAD\x00\x51", 3, "Telogy Networks", false },
350     {"\xAD\x00\x55", 3, "HylaFAX",   false },
351     {"\xAD\x00\x5C", 3, "IBM", false },
352     {"\xAD\x00\x98", 3, "unknown - USA 98", true },
353     {"\xB5\x00\x01", 3, "Picturetel", false },
354     {"\xB5\x00\x20", 3, "Conexant",  false },
355     {"\xB5\x00\x22", 3, "Comsat",    false },
356     {"\xB5\x00\x24", 3, "Octel",     false },
357     {"\xB5\x00\x26", 3, "ROLM",      false },
358     {"\xB5\x00\x28", 3, "SOFNET",    false },
359     {"\xB5\x00\x29", 3, "TIA TR-29 Committee", false },
360     {"\xB5\x00\x2A", 3, "STF Tech",  false },
361     {"\xB5\x00\x2C", 3, "HKB",       false },
362     {"\xB5\x00\x2E", 3, "Delrina",   false },
363     {"\xB5\x00\x30", 3, "Dialogic",  false },
364     {"\xB5\x00\x32", 3, "Applied Synergy", false },
365     {"\xB5\x00\x34", 3, "Syncro Development", false },
366     {"\xB5\x00\x36", 3, "Genoa",     false },
367     {"\xB5\x00\x38", 3, "Texas Instruments", false },
368     {"\xB5\x00\x3A", 3, "IBM",       false },
369     {"\xB5\x00\x3C", 3, "ViaSat",    false },
370     {"\xB5\x00\x3E", 3, "Ericsson",  false },
371     {"\xB5\x00\x42", 3, "Bogosian",  false },
372     {"\xB5\x00\x44", 3, "Adobe",     false },
373     {"\xB5\x00\x46", 3, "Fremont Communications", false },
374     {"\xB5\x00\x48", 3, "Hayes",     false },
375     {"\xB5\x00\x4A", 3, "Lucent",    false },
376     {"\xB5\x00\x4C", 3, "Data Race", false },
377     {"\xB5\x00\x4E", 3, "TRW",       false },
378     {"\xB5\x00\x52", 3, "Audiofax",  false },
379     {"\xB5\x00\x54", 3, "Computer Automation", false },
380     {"\xB5\x00\x56", 3, "Serca",     false },
381     {"\xB5\x00\x58", 3, "Octocom",   false },
382     {"\xB5\x00\x5C", 3, "Power Solutions", false },
383     {"\xB5\x00\x5A", 3, "Digital Sound", false },
384     {"\xB5\x00\x5E", 3, "Pacific Data", false },
385     {"\xB5\x00\x60", 3, "Commetrex", false },
386     {"\xB5\x00\x62", 3, "BrookTrout", false },
387     {"\xB5\x00\x64", 3, "Gammalink", false },
388     {"\xB5\x00\x66", 3, "Castelle",  false },
389     {"\xB5\x00\x68", 3, "Hybrid Fax", false },
390     {"\xB5\x00\x6A", 3, "Omnifax",   false },
391     {"\xB5\x00\x6C", 3, "HP",        false },
392     {"\xB5\x00\x6E", 3, "Microsoft", false },
393     {"\xB5\x00\x72", 3, "Speaking Devices", false },
394     {"\xB5\x00\x74", 3, "Compaq",    false },
395 /*
396     {"\xB5\x00\x76", 3, "Trust - Cryptek", false },     // collision with Microsoft
397 */
398     {"\xB5\x00\x76", 3, "Microsoft", false },           /* uses LSB for country but MSB for manufacturer */
399     {"\xB5\x00\x78", 3, "Cylink",    false },
400     {"\xB5\x00\x7A", 3, "Pitney Bowes", false },
401     {"\xB5\x00\x7C", 3, "Digiboard", false },
402     {"\xB5\x00\x7E", 3, "Codex",     false },
403     {"\xB5\x00\x82", 3, "Wang Labs", false },
404     {"\xB5\x00\x84", 3, "Netexpress Communications", false },
405     {"\xB5\x00\x86", 3, "Cable-Sat", false },
406     {"\xB5\x00\x88", 3, "MFPA",      false },
407     {"\xB5\x00\x8A", 3, "Telogy Networks", false },
408     {"\xB5\x00\x8E", 3, "Telecom Multimedia Systems", false },
409     {"\xB5\x00\x8C", 3, "AT&T",      false },
410     {"\xB5\x00\x92", 3, "Nuera",     false },
411     {"\xB5\x00\x94", 3, "K56flex",   false },
412     {"\xB5\x00\x96", 3, "MiBridge",  false },
413     {"\xB5\x00\x98", 3, "Xerox",     false },
414     {"\xB5\x00\x9A", 3, "Fujitsu",   false },
415     {"\xB5\x00\x9B", 3, "Fujitsu",   false },
416     {"\xB5\x00\x9C", 3, "Natural Microsystems",  false },
417     {"\xB5\x00\x9E", 3, "CopyTele",  false },
418     {"\xB5\x00\xA2", 3, "Murata",    false },
419     {"\xB5\x00\xA4", 3, "Lanier",    false },
420     {"\xB5\x00\xA6", 3, "Qualcomm",  false },
421     {"\xB5\x00\xAA", 3, "HylaFAX",   false },           /* they did it backwards for a while */
422     {NULL}
423 };
424
425 void hylafax_nsf_decode _P2(( nsf, nsfSize ), 
426                              unsigned char * nsf, int nsfSize )
427 {
428 const char * vendor = NULL;
429 const char * model = NULL;
430 const NSFData * p;
431 const ModelData * pp;
432
433     for( p = KnownNSF; p->vendorId; p++ ){
434         if( nsfSize >= p->vendorIdSize &&
435             memcmp( p->vendorId, &nsf[0], p->vendorIdSize )==0 ){
436             if( p->vendorName )
437                 vendor = p->vendorName;
438             if( p->knownModels ){
439                 for( pp = p->knownModels; pp->modelId; pp++ )
440                     if( nsfSize >= p->modelIdPos + p->modelIdSize &&
441                         memcmp( pp->modelId, &nsf[p->modelIdPos], p->modelIdSize )==0 )
442                         model = pp->modelName;
443             }
444             break;
445         }
446     }
447     if ( vendor != NULL || model != NULL )
448         lprintf( L_MESG, "NSF: vendor=%s, model=%s",
449                         vendor != NULL? vendor: "<unknown>",
450                         model  != NULL? model : "<unknown>" );
451 }
452
453 #endif