Imported Upstream version 2.9.0
[debian/cc1111] / device / examples / ds390 / ow390 / owfile.c
1 #define DEBUG_OW_FILE 0
2 #if DEBUG_OW_FILE
3 #include <stdio.h>
4 #endif
5 //---------------------------------------------------------------------------
6 // Copyright (C) 2000 Dallas Semiconductor Corporation, All Rights Reserved.
7 // 
8 // Permission is hereby granted, free of charge, to any person obtaining a 
9 // copy of this software and associated documentation files (the "Software"), 
10 // to deal in the Software without restriction, including without limitation 
11 // the rights to use, copy, modify, merge, publish, distribute, sublicense, 
12 // and/or sell copies of the Software, and to permit persons to whom the 
13 // Software is furnished to do so, subject to the following conditions:
14 // 
15 // The above copyright notice and this permission notice shall be included 
16 // in all copies or substantial portions of the Software.
17 // 
18 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 
19 // OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 
20 // MERCHANTABILITY,  FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 
21 // IN NO EVENT SHALL DALLAS SEMICONDUCTOR BE LIABLE FOR ANY CLAIM, DAMAGES 
22 // OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, 
23 // ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 
24 // OTHER DEALINGS IN THE SOFTWARE.
25 // 
26 // Except as contained in this notice, the name of Dallas Semiconductor 
27 // shall not be used except as stated in the Dallas Semiconductor 
28 // Branding Policy. 
29 //---------------------------------------------------------------------------
30 //
31 // owFile.C: Rudimentary level functions for reading and writing TMEX
32 //             files on NVRAM iButton using the packet level functions.
33 //
34 // Version:  2.00
35 //
36 // History:
37 //           1.02 -> 1.03  Removed caps in #includes for Linux capatibility
38 //           1.03 -> 2.00  Changed 'MLan' to 'ow'. Added support for 
39 //                         multiple ports.  
40 //
41
42 #include "ownet.h"
43
44 //--------------------------------------------------------------------------
45 // Read a TMEX file return it in the provided buffer. 
46 //
47 // 'portnum'  - number 0 to MAX_PORTNUM-1.  This number was provided to
48 //              OpenCOM to indicate the port number.
49 // 'filename' - pointer to five byte filename to read where the
50 //              the first four bytes are the name and the fifth is
51 //              the extension (0 to 101 decimal).             
52 // 'buf'      - pointer to a buffer to place the file information into.
53 //              This may need to be as large as 7084 bytes.
54 // 
55 // Supported devices: All devices supported by owReadPacketStd
56 //
57 // Returns:  >=0  success, number of bytes in the buffer
58 //           <0   failed to read the file (error code) 
59 //
60 int owReadFile(int portnum, uchar *filename, uchar *buf)
61 {  
62   uchar dirpg=0,pgbuf[32],filepg=0;
63   char pglen;
64   ushort bufcnt=0,i;
65                
66 #if DEBUG_OW_FILE
67    printf ("owReadFile: %s\n", filename);
68 #endif
69    // loop read directory pages until the file entry is found
70    do
71    {
72       // read a directory page
73       pglen = owReadPacketStd(portnum,TRUE,dirpg,pgbuf);  
74        
75       // check for reading error
76       if (pglen <= 0)
77          return READ_ERROR;
78          
79       // if this is the first page make sure this is a directory
80       // structure
81       if (  ((dirpg == 0) && 
82             ((pgbuf[0] != 0xAA) || (pgbuf[1] != 0) || (pglen < 7)))
83             ||
84             ((pglen-1) % 7) ) 
85          return INVALID_DIR;
86       
87       // loop through each file entry in directory page (page 0 exception)
88       for (i = (dirpg == 0) ? 7 : 0; i < 28; i += 7)
89       {     
90          // file entry found?
91          if ((filename[0] == pgbuf[i]) &&
92              (filename[1] == pgbuf[i+1]) &&
93              (filename[2] == pgbuf[i+2]) &&
94              (filename[3] == pgbuf[i+3]) &&
95              (filename[4] == (pgbuf[i+4] & 0x7F)) )
96          {
97             // get the file starting page number
98             filepg = pgbuf[i+5];
99 #if DEBUG_OW_FILE
100             printf ("owReadFile: file %s starts at %d\n", filename, filepg);
101 #endif
102             break;
103          }
104       }
105       
106       // get the next directory page (from page pointer) 
107       dirpg = pgbuf[pglen-1];
108    }
109    while (dirpg && (filepg == 0));  
110    
111    // check if file found
112    if (!filepg)
113       return NO_FILE;
114    
115    // loop to read the file pages
116    do
117    {
118       // read a file page
119       pglen = owReadPacketStd(portnum,TRUE,filepg,pgbuf);  
120       
121       // check result of read
122       if (pglen <= 0) {
123         return READ_ERROR;
124       }
125    
126       // append the page data to the buffer
127       for (i = 0; i < (pglen - 1); i++)
128          buf[bufcnt++] = pgbuf[i];
129
130       // get the next file page (from page pointer) 
131       filepg = pgbuf[pglen-1];
132    }
133    while (filepg);
134
135    // return the number of data bytes read
136    return bufcnt;
137 }
138
139
140 //--------------------------------------------------------------------------
141 // Format and Write a TMEX file. 
142 // Any previous files will be removed in the Format operation.
143 // The file length 'fllen' can be up to:
144 //     420  bytes for a DS1993   
145 //     1736 bytes for a DS1995
146 //     7084 bytes for a DS1996.
147 //
148 // 'portnum'  - number 0 to MAX_PORTNUM-1.  This number was provided to
149 //              OpenCOM to indicate the port number.
150 // 'filename' - pointer to five byte filename to write where the
151 //              the first four bytes are the name and the fifth is
152 //              the extension (0 to 101 decimal).             
153 // 'buf'      - pointer to a buffer containing the file information to write.
154 //
155 // Supported devices: DS1993, DS1994, DS1995, DS1996
156 //
157 // Returns:  TRUE(1) success, device formated and file written
158 //           <0      failed to read the file (error code) 
159 //     
160 //
161 int owFormatWriteFile(int portnum, uchar *filename, int fllen, uchar *buf)
162 {
163    uchar dummydir[] = { 0xAA, 0, 0x80, 0x01, 0, 0, 0, 0 },
164       newdir[] = { 0xAA, 0, 0x80, 0x01, 0, 0, 0, ' ', ' ', ' ', ' ', 0, 1, 1, 0 },
165       bmpg1[] = { 0x03,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0x02 },
166       bmpg2[] = { 0,0,0,0,0 }, pgbuf[32];   
167    int i,numdirpgs,flpg,bmpg1len,bmpg2len,cntleft,pos,numpgs;
168
169 #if DEBUG_OW_FILE
170    printf ("owFormatWriteFile: %s %d\n", filename, fllen);
171 #endif
172    // calculate the number of pages needed to write the file
173    numpgs = (fllen / 28) + ((fllen % 28) ? 1 : 0);
174    
175    // put the file in the newdirectory
176    for(i = 0; i < 5; i++)
177       newdir[i+7] = filename[i];
178    newdir[13] = (uchar)numpgs;
179    
180    // set the directory pages for formatting device depending on the device type
181    switch (SerialNum[portnum][0])  //jpe
182    {
183       case 0x06:  // DS1993
184          // check for file too big
185          if (numpgs > 15)
186             return FILE_TOO_BIG;
187          // set the bitmap in the directory page
188          for (i = 0; i < numpgs; i++)
189             bitacc(WRITE_FUNCTION,1,i+1,&newdir[3]);
190          numdirpgs = 1;
191          flpg = 1;   
192          newdir[12] = (uchar)flpg;
193          break;                               
194       case 0x0A:  // DS1995
195          // check for file too big
196          if (numpgs > 62)
197             return FILE_TOO_BIG;       
198          // set to external bitmap file
199          newdir[2] = 0; 
200          // set the bitmap in the first (and only) bitmap page
201          for (i = 0; i < numpgs; i++)
202             bitacc(WRITE_FUNCTION,1,i+2,&bmpg1[0]);
203          numdirpgs = 2;
204          flpg = 2; 
205          newdir[12] = (uchar)flpg; // startpage
206          bmpg1len = 9;                          
207          newdir[3] = 0; // remove local bitmap
208          newdir[5] = 1; // bitmap start page
209          newdir[6] = 1; // bitmap number of pages
210          break;                               
211       case 0x0C:  // DS1996 
212          // check for file too big
213          if (numpgs > 253)
214             return FILE_TOO_BIG;
215          // set to external bitmap file
216          newdir[2] = 0; 
217          // set the 3rd bitmap page in the bitmap
218          bitacc(WRITE_FUNCTION,1,2,&bmpg1[0]);
219          
220          // set the bitmap in the first and second bitmap page
221          for (i = 0; i < numpgs; i++)
222          {
223             if (i <= 221)
224                bitacc(WRITE_FUNCTION,1,i+3,&bmpg1[0]);  
225             else
226                bitacc(WRITE_FUNCTION,1,i-221,&bmpg2[0]);  
227          }   
228          numdirpgs = 3;
229          flpg = 3;   
230          newdir[12] = (uchar)flpg; // startpage
231          bmpg1len = 29;  
232          bmpg2len = 5;  
233          newdir[3] = 0; // remove local bitmap
234          newdir[5] = 1; // bitmap start page
235          newdir[6] = 2; // bitmap number of pages
236          break;                               
237       default:
238          return WRONG_TYPE;
239    }
240    
241    // write a dummy directory in page 0 in case we get interrupted
242    if (!owWritePacketStd(portnum,0,dummydir,8,FALSE,FALSE))
243       return WRITE_ERROR;
244    
245    // loop to write the file in contiguous pages start with flpg
246    cntleft = fllen;  // count of bytes left to write  
247    pos = 0; // current position in the buffer to write
248    while (cntleft > 0)
249    {
250       // get a page of data to write
251       for (i = 0; i < ((cntleft > 28) ? 28 : cntleft); i++)
252          pgbuf[i] = buf[pos++];
253                                     
254       // adjust the bytes left
255       cntleft -= i;
256                                     
257       // set the next page pointer   
258       pgbuf[i] = (cntleft == 0) ? 0 : flpg+1;
259       
260       // write the page and check to result
261       if (!owWritePacketStd(portnum,flpg,pgbuf,i+1,FALSE,FALSE))
262          return WRITE_ERROR;
263       
264       // set the next page
265       flpg++;      
266    } 
267
268    // now write the second bitmap page if needed
269    if (numdirpgs == 3)
270       if (!owWritePacketStd(portnum,2,bmpg2,bmpg2len,FALSE,FALSE))
271          return WRITE_ERROR;
272
273    // now write the first bitmap page if needed
274    if (numdirpgs >= 2)
275       if (!owWritePacketStd(portnum,1,bmpg1,bmpg1len,FALSE,FALSE))
276          return WRITE_ERROR;
277    
278    // now write the directory page
279    if (!owWritePacketStd(portnum,0,newdir,15,FALSE,FALSE))
280       return WRITE_ERROR;
281    
282    // success file written
283    return TRUE;
284
285