Add access with W1-Kernelmodule
[owTools.git] / src / owW1Interface.cpp
1 // Copyright (c) 2017, Tobias Mueller tm(at)tm3d.de
2 // All rights reserved.
3 //
4 // Redistribution and use in source and binary forms, with or without
5 // modification, are permitted provided that the following conditions are
6 // met:
7 //
8 //  * Redistributions of source code must retain the above copyright
9 //    notice, this list of conditions and the following disclaimer.
10 //  * Redistributions in binary form must reproduce the above copyright
11 //    notice, this list of conditions and the following disclaimer in the
12 //    documentation and/or other materials provided with the
13 //    distribution.
14 //  * All advertising materials mentioning features or use of this
15 //    software must display the following acknowledgement: This product
16 //    includes software developed by tm3d.de and its contributors.
17 //  * Neither the name of tm3d.de nor the names of its contributors may
18 //    be used to endorse or promote products derived from this software
19 //    without specific prior written permission.
20 //
21 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
22 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
23 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
24 // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
25 // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
26 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
27 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
28 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
29 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
30 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
31 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
32
33
34 #include "owW1Interface.h"
35 #include <stdio.h>
36 #include <stdlib.h>
37 #include <stdint.h>
38 #include <sys/mman.h>
39 #include <fcntl.h>    /* For O_RDWR */
40 #include <unistd.h>
41 #include <pthread.h>
42 #include <sched.h>
43 #include <memory.h>
44 #include <strings.h>
45 #include <dirent.h> 
46
47
48 snum_t owW1Interface::getSnum(const char *s) {
49         snum_t snum;
50         int res=sscanf( s,"%02hhx-%02hhx%02hhx%02hhx%02hhx%02hhx%02hhx",&snum.byte[0],&snum.byte[6],&snum.byte[5],&snum.byte[4],&snum.byte[3],&snum.byte[2],&snum.byte[1]);
51         if (res==7) {
52                 std::vector<uint8_t> id;
53                 for(int i=0;i<7;i++) id.push_back(snum.byte[i]);
54                 snum.byte[7]=calcCRC8(id);
55         } else snum.num=0;
56         return snum;
57         
58 }
59 void owW1Interface::getStrnum(snum_t snum,char *s) {
60         sprintf(s,"%02x-%02x%02x%02x%02x%02x%02x",snum.byte[0],snum.byte[6],snum.byte[5],snum.byte[4],snum.byte[3],snum.byte[2],snum.byte[1]);
61 }
62
63
64 int owW1Interface::InitAdapter(uint8_t nr) {
65         d = opendir("/sys/bus/w1/devices");
66         if (d) {
67                 printf("W1 direcotry ok\n");
68         } else {
69                 log->set(OWLOG_ERROR,"W1 directory not found!");
70                 return 0;
71         }
72                 
73         return 1;       
74 }
75 int owW1Interface::Reset() {
76         return 1;
77 }
78 uint8_t owW1Interface::sendrecivBit(uint8_t bit)  {
79         return 1;
80 }
81 uint8_t owW1Interface::sendrecivByte(uint8_t byte) {
82         return 0xFF;
83 }
84 void owW1Interface::ReleaseAdapter() {}
85 int owW1Interface::owFirst() {
86         struct dirent *dir;
87         d = opendir("/sys/bus/w1/devices");
88         if (d==0) {
89                 log->set(OWLOG_ERROR,"W1 directory not found!");
90                 return 0;
91         } 
92         while ((dir = readdir(d)) != NULL)   {
93                 snum_t snum=getSnum(dir->d_name);
94                 if (snum.num!=0) {
95                         for (int i=0;i<8;i++) ROM_NO[i]=snum.byte[i];
96                         return 1;
97                 }
98         }
99         return 0;
100 }
101 int owW1Interface::owNext() {
102         struct dirent *dir;
103         while ((dir = readdir(d)) != NULL)   {
104                 snum_t snum=getSnum(dir->d_name);
105                 if (snum.num!=0) {
106                         for (int i=0;i<8;i++) ROM_NO[i]=snum.byte[i];
107                         return 1;
108                 }
109         }
110         return 0;
111 }
112 FILE* owW1Interface::openW1Stream(snum_t snum) {
113         char s[200];
114         FILE *f=NULL;
115         sprintf(s,"/sys/bus/w1/devices/%02x-%02x%02x%02x%02x%02x%02x/rw",snum.byte[0],snum.byte[6],snum.byte[5],snum.byte[4],snum.byte[3],snum.byte[2],snum.byte[1]);
116         f=fopen(s,"rb+");
117         if (f==NULL) {
118                 printf("Error open rw-file, try to remove device-modules\n");
119                 int res=system("rmmod w1_therm w1_smem w1_ds2433");
120                 f=fopen(s,"rb+");
121                 if (f!=NULL) {
122                         setbuf(f,NULL);
123                         return f;
124                 }
125                 log->set(OWLOG_ERROR,"device-directory not found! (%i)",res);
126         } else {
127                 setbuf(f,NULL);
128                 return f;
129         }
130                 
131         return NULL;
132 }
133
134 int owW1Interface::Communicate(std::vector<uint8_t> *data, int scount, int rcount) {
135         int pointer=0;
136         if ((*data)[0]==0x55) {
137                 for(int i=0;i<8;i++) activedevice.byte[i]=(*data)[i+1];
138                 //printf("Setaktiv %016llX\n",(unsigned long long)activedevice.num);
139                 pointer=8;
140         }
141         if (scount>pointer) { //noch mehr senden
142                 FILE *f;
143                 f=openW1Stream(activedevice);
144                 if (f!=NULL) {
145                         uint8_t w[256],r[256];
146                         std::copy(data->begin()+pointer, data->end(), w);
147                         fwrite(w,1,scount-pointer,f);
148                         int res=fread(r,1,rcount,f);
149                         for(int i=0;i<res;i++) {
150                                 data->push_back(r[i]);
151                         }
152                         for(int i=0;i<(rcount-res);i++) {
153                                 data->push_back(0xFF);
154                         }
155                 }
156         }
157         return 1;
158 }