- fixed dvb scan
[enigma2.git] / lib / dvb / db.cpp
1 #include <errno.h>
2 #include <lib/dvb/db.h>
3 #include <lib/dvb/frontend.h>
4 #include <lib/base/eerror.h>
5 #include <lib/dvb_si/sdt.h>
6 #include <lib/dvb_si/descriptor_tag.h>
7 #include <lib/dvb_si/service_descriptor.h>
8 #include <lib/dvb_si/satellite_delivery_system_descriptor.h>
9
10 DEFINE_REF(eDVBService);
11
12 eDVBService::eDVBService()
13 {
14 }
15
16 eDVBService::~eDVBService()
17 {
18 }
19
20 eDVBService &eDVBService::operator=(const eDVBService &s)
21 {
22         m_service_name = s.m_service_name;
23         m_provider_name = s.m_provider_name;
24         m_flags = s.m_flags;
25         m_ca = s.m_ca;
26         m_cache = s.m_cache;
27         return *this;
28 }
29
30 DEFINE_REF(eDVBDB);
31
32 eDVBDB::eDVBDB()
33 {
34         eDebug("---- opening lame channel db");
35         FILE *f=fopen("lamedb", "rt");
36         if (!f)
37                 return;
38         char line[256];
39         if ((!fgets(line, 256, f)) || strncmp(line, "eDVB services", 13))
40         {
41                 eDebug("not a servicefile");
42                 fclose(f);
43                 return;
44         }
45         eDebug("reading services");
46         if ((!fgets(line, 256, f)) || strcmp(line, "transponders\n"))
47         {
48                 eDebug("services invalid, no transponders");
49                 fclose(f);
50                 return;
51         }
52         
53         // clear all transponders
54
55         while (!feof(f))
56         {
57                 if (!fgets(line, 256, f))
58                         break;
59                 if (!strcmp(line, "end\n"))
60                         break;
61                 int dvb_namespace=-1, transport_stream_id=-1, original_network_id=-1;
62                 sscanf(line, "%x:%x:%x", &dvb_namespace, &transport_stream_id, &original_network_id);
63                 if (original_network_id == -1)
64                         continue;
65                 eDVBChannelID channelid = eDVBChannelID(
66                         eDVBNamespace(dvb_namespace), 
67                         eTransportStreamID(transport_stream_id), 
68                         eOriginalNetworkID(original_network_id));
69                 
70                 ePtr<eDVBFrontendParameters> feparm = new eDVBFrontendParameters;
71                 while (!feof(f))
72                 {
73                         fgets(line, 256, f);
74                         if (!strcmp(line, "/\n"))
75                                 break;
76                         if (line[1]=='s')
77                         {
78                                 eDVBFrontendParametersSatellite sat;
79                                 int frequency, symbol_rate, polarisation, fec, orbital_position, inversion;
80                                 sscanf(line+2, "%d:%d:%d:%d:%d:%d", &frequency, &symbol_rate, &polarisation, &fec, &inversion, &orbital_position);
81                                 sat.frequency = frequency;
82                                 sat.symbol_rate = symbol_rate;
83                                 sat.polarisation = polarisation;
84                                 sat.fec = fec;
85                                 sat.orbital_position = orbital_position;
86                                 sat.inversion = inversion;
87                                 // ...
88 //                              t.setSatellite(frequency, symbol_rate, polarisation, fec, sat, inversion);
89                                 feparm->setDVBS(sat);
90                         }
91                         if (line[1]=='c')
92                         {
93                                 int frequency, symbol_rate, inversion=0, modulation=3;
94                                 sscanf(line+2, "%d:%d:%d:%d", &frequency, &symbol_rate, &inversion, &modulation);
95 //                              t.setCable(frequency, symbol_rate, inversion, modulation);
96                         }
97                 }
98                 addChannelToList(channelid, feparm);
99         }
100
101         if ((!fgets(line, 256, f)) || strcmp(line, "services\n"))
102         {
103                 eDebug("services invalid, no services");
104                 return;
105         }
106         
107         // clear all services
108         
109         int count=0;
110
111         while (!feof(f))
112         {
113                 if (!fgets(line, 256, f))
114                         break;
115                 if (!strcmp(line, "end\n"))
116                         break;
117
118                 int service_id=-1, dvb_namespace, transport_stream_id=-1, original_network_id=-1, service_type=-1, service_number=-1;
119                 sscanf(line, "%x:%x:%x:%x:%d:%d", &service_id, &dvb_namespace, &transport_stream_id, &original_network_id, &service_type, &service_number);
120                 if (service_number == -1)
121                         continue;
122                 ePtr<eDVBService> s = new eDVBService;
123                 eServiceReferenceDVB ref = 
124                                                 eServiceReferenceDVB(
125                                                 eDVBNamespace(dvb_namespace),
126                                                 eTransportStreamID(transport_stream_id),
127                                                 eOriginalNetworkID(original_network_id),
128                                                 eServiceID(service_id),
129                                                 service_type);
130                 count++;
131                 fgets(line, 256, f);
132                 if (strlen(line))
133                         line[strlen(line)-1]=0;
134                 s->m_service_name=line;
135                 fgets(line, 256, f);
136                 if (strlen(line))
137                         line[strlen(line)-1]=0;
138
139                 std::string str=line;
140
141                 if (str[1]!=':')        // old ... (only service_provider)
142                 {
143                         s->m_provider_name=line;
144                 } else
145                         while ((!str.empty()) && str[1]==':') // new: p:, f:, c:%02d...
146                         {
147                                 unsigned int c=str.find(',');
148                                 char p=str[0];
149                                 std::string v;
150                                 if (c == std::string::npos)
151                                 {
152                                         v=str.substr(2);
153                                         str="";
154                                 } else
155                                 {
156                                         v=str.substr(2, c-2);
157                                         str=str.substr(c+1);
158                                 }
159 //                              eDebug("%c ... %s", p, v.c_str());
160                                 if (p == 'p')
161                                         s->m_provider_name=v;
162                                 else if (p == 'f')
163                                 {
164                                         sscanf(v.c_str(), "%x", &s->m_flags);
165                                 } else if (p == 'c')
166                                 {
167                                         int cid, val;
168                                         sscanf(v.c_str(), "%02d%04x", &cid, &val);
169                                         s->m_cache[cid]=val;
170                                 } else if (p == 'C')
171                                 {
172                                         int val;
173                                         sscanf(v.c_str(), "%04x", &val);
174                                         s->m_ca.insert(val);
175                                 }
176                         }
177                 addService(ref, s);
178         }
179
180         eDebug("loaded %d services", count);
181         
182         fclose(f);
183         
184 }
185
186 eDVBDB::~eDVBDB()
187 {
188         eDebug("---- saving lame channel db");
189         FILE *f=fopen("lamedb", "wt");
190         int channels=0, services=0;
191         if (!f)
192                 eFatal("couldn't save lame channel db!"); 
193         fprintf(f, "eDVB services /3/\n");
194         fprintf(f, "transponders\n");
195         for (std::map<eDVBChannelID, channel>::const_iterator i(m_channels.begin());
196                         i != m_channels.end(); ++i)
197         {
198                 const eDVBChannelID &chid = i->first;
199                 const channel &ch = i->second;
200                 
201                 fprintf(f, "%08x:%04x:%04x\n", chid.dvbnamespace.get(),
202                                 chid.transport_stream_id.get(), chid.original_network_id.get());
203                 eDVBFrontendParametersSatellite sat;
204                 if (!ch.m_frontendParameters->getDVBS(sat))
205                 {
206                         fprintf(f, "\ts %d:%d:%d:%d:%d:%d\n", 
207                                 sat.frequency, sat.symbol_rate,
208                                 sat.polarisation, sat.fec, sat.inversion,
209                                 sat.orbital_position);
210                 }
211                 fprintf(f, "/\n");
212                 channels++;
213         }
214         fprintf(f, "end\nservices\n");
215         
216         for (std::map<eServiceReferenceDVB, ePtr<eDVBService> >::iterator i(m_services.begin());
217                 i != m_services.end(); ++i)
218         {
219                 const eServiceReferenceDVB &s = i->first;
220                 fprintf(f, "%04x:%08x:%04x:%04x:%d:%d\n", 
221                                 s.getServiceID().get(), s.getDVBNamespace().get(), 
222                                 s.getTransportStreamID().get(),s.getOriginalNetworkID().get(), 
223                                 s.getServiceType(),
224                                 0);
225                 
226                 fprintf(f, "%s\n", i->second->m_service_name.c_str());
227                 fprintf(f, "p:%s", i->second->m_provider_name.c_str());
228                 for (std::set<int>::const_iterator ca(i->second->m_ca.begin());
229                         ca != i->second->m_ca.end(); ++ca)
230                         fprintf(f, ",C:%04x", *ca);
231                 fprintf(f, "\n");
232                 services++;
233         }
234         fprintf(f, "end\nHave a lot of bugs!\n");
235         eDebug("saved %d channels and %d services!", channels, services);
236         fclose(f);
237 }
238
239 RESULT eDVBDB::addChannelToList(const eDVBChannelID &id, iDVBFrontendParameters *feparm)
240 {
241         channel ch;
242         assert(feparm);
243         ch.m_frontendParameters = feparm;
244         m_channels.insert(std::pair<eDVBChannelID, channel>(id, ch));
245         return 0;
246 }
247
248 RESULT eDVBDB::removeChannel(const eDVBChannelID &id)
249 {
250         m_channels.erase(id);
251         return 0;
252 }
253
254 RESULT eDVBDB::getChannelFrontendData(const eDVBChannelID &id, ePtr<iDVBFrontendParameters> &parm)
255 {
256         std::map<eDVBChannelID, channel>::iterator i = m_channels.find(id);
257         if (i == m_channels.end())
258         {
259                 parm = 0;
260                 return -ENOENT;
261         }
262         parm = i->second.m_frontendParameters;
263         return 0;
264 }
265
266 RESULT eDVBDB::addService(const eServiceReferenceDVB &serviceref, eDVBService *service)
267 {
268         m_services.insert(std::pair<eServiceReferenceDVB, ePtr<eDVBService> >(serviceref, service));
269         return 0;
270 }
271
272 RESULT eDVBDB::getService(const eServiceReferenceDVB &reference, ePtr<eDVBService> &service)
273 {
274         std::map<eServiceReferenceDVB, ePtr<eDVBService> >::iterator i;
275         i = m_services.find(reference);
276         if (i == m_services.end())
277         {
278                 service = 0;
279                 return -ENOENT;
280         }
281         service = i->second;
282         return 0;
283 }
284