~ubuntu-branches/ubuntu/precise/me-tv/precise-proposed

« back to all changes in this revision

Viewing changes to src/libdvben50221/en50221_stdcam_hlci.c

  • Committer: Bazaar Package Importer
  • Author(s): Philipp Kern
  • Date: 2008-07-23 14:03:56 UTC
  • mfrom: (1.1.3 upstream) (3.1.1 lenny)
  • Revision ID: james.westby@ubuntu.com-20080723140356-m6ze7fbkydes42c7
Tags: 0.5.33-3
Fix xine-lib ffmpeg dependency.

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
/*
2
 
        en50221 encoder An implementation for libdvb
3
 
        an implementation for the en50221 transport layer
4
 
 
5
 
        Copyright (C) 2006 Andrew de Quincey (adq_dvb@lidskialf.net)
6
 
 
7
 
        This program is free software; you can redistribute it and/or modify
8
 
        it under the terms of the GNU Lesser General Public License as
9
 
        published by the Free Software Foundation; either version 2.1 of
10
 
        the License, or (at your option) any later version.
11
 
 
12
 
        This program is distributed in the hope that it will be useful,
13
 
        but WITHOUT ANY WARRANTY; without even the implied warranty of
14
 
        MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15
 
        GNU Lesser General Public License for more details.
16
 
 
17
 
        You should have received a copy of the GNU Lesser General Public
18
 
        License along with this library; if not, write to the Free Software
19
 
        Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
20
 
*/
21
 
 
22
 
#include <stdio.h>
23
 
#include <unistd.h>
24
 
#include <limits.h>
25
 
#include <string.h>
26
 
#include <errno.h>
27
 
#include <libdvbapi/dvbca.h>
28
 
#include "en50221_app_utils.h"
29
 
#include "en50221_app_tags.h"
30
 
#include "en50221_stdcam.h"
31
 
 
32
 
 
33
 
struct en50221_stdcam_hlci {
34
 
        struct en50221_stdcam stdcam;
35
 
 
36
 
        int cafd;
37
 
        int slotnum;
38
 
        int initialised;
39
 
        struct en50221_app_send_functions sendfuncs;
40
 
};
41
 
 
42
 
static void en50221_stdcam_hlci_destroy(struct en50221_stdcam *stdcam, int closefd);
43
 
static enum en50221_stdcam_status en50221_stdcam_hlci_poll(struct en50221_stdcam *stdcam);
44
 
static int hlci_cam_added(struct en50221_stdcam_hlci *hlci);
45
 
static int hlci_send_data(void *arg, uint16_t session_number,
46
 
                          uint8_t * data, uint16_t data_length);
47
 
static int hlci_send_datav(void *arg, uint16_t session_number,
48
 
                           struct iovec *vector, int iov_count);
49
 
 
50
 
 
51
 
 
52
 
 
53
 
struct en50221_stdcam *en50221_stdcam_hlci_create(int cafd, int slotnum)
54
 
{
55
 
        // try and allocate space for the HLCI stdcam
56
 
        struct en50221_stdcam_hlci *hlci =
57
 
                malloc(sizeof(struct en50221_stdcam_hlci));
58
 
        if (hlci == NULL) {
59
 
                return NULL;
60
 
        }
61
 
        memset(hlci, 0, sizeof(struct en50221_stdcam_hlci));
62
 
 
63
 
        // create the sendfuncs
64
 
        hlci->sendfuncs.arg = hlci;
65
 
        hlci->sendfuncs.send_data = hlci_send_data;
66
 
        hlci->sendfuncs.send_datav = hlci_send_datav;
67
 
 
68
 
        // create the resources (NOTE: we just use fake session numbers here)
69
 
        hlci->stdcam.ai_resource = en50221_app_ai_create(&hlci->sendfuncs);
70
 
        hlci->stdcam.ai_session_number = 0;
71
 
        hlci->stdcam.ca_resource = en50221_app_ca_create(&hlci->sendfuncs);
72
 
        hlci->stdcam.ca_session_number = 1;
73
 
//      hlci->stdcam.mmi_resource = en50221_app_mmi_create(&hlci->sendfuncs);
74
 
        hlci->stdcam.mmi_session_number = -1;
75
 
 
76
 
        // done
77
 
        hlci->stdcam.destroy = en50221_stdcam_hlci_destroy;
78
 
        hlci->stdcam.poll = en50221_stdcam_hlci_poll;
79
 
        hlci->slotnum = slotnum;
80
 
        hlci->cafd = cafd;
81
 
        return &hlci->stdcam;
82
 
}
83
 
 
84
 
static void en50221_stdcam_hlci_destroy(struct en50221_stdcam *stdcam, int closefd)
85
 
{
86
 
        struct en50221_stdcam_hlci *hlci = (struct en50221_stdcam_hlci *) stdcam;
87
 
 
88
 
        if (hlci->stdcam.ai_resource)
89
 
                en50221_app_ai_destroy(hlci->stdcam.ai_resource);
90
 
        if (hlci->stdcam.ca_resource)
91
 
                en50221_app_ca_destroy(hlci->stdcam.ca_resource);
92
 
        if (hlci->stdcam.mmi_resource)
93
 
                en50221_app_mmi_destroy(hlci->stdcam.mmi_resource);
94
 
 
95
 
        if (closefd)
96
 
                close(hlci->cafd);
97
 
 
98
 
        free(hlci);
99
 
}
100
 
 
101
 
static enum en50221_stdcam_status en50221_stdcam_hlci_poll(struct en50221_stdcam *stdcam)
102
 
{
103
 
        struct en50221_stdcam_hlci *hlci = (struct en50221_stdcam_hlci *) stdcam;
104
 
 
105
 
        switch(dvbca_get_cam_state(hlci->cafd, hlci->slotnum)) {
106
 
        case DVBCA_CAMSTATE_MISSING:
107
 
                hlci->initialised = 0;
108
 
                break;
109
 
 
110
 
        case DVBCA_CAMSTATE_READY:
111
 
        case DVBCA_CAMSTATE_INITIALISING:
112
 
                if (!hlci->initialised)
113
 
                        hlci_cam_added(hlci);
114
 
                break;
115
 
        }
116
 
 
117
 
        // delay to prevent busy loop
118
 
        usleep(10);
119
 
 
120
 
        if (!hlci->initialised) {
121
 
                return EN50221_STDCAM_CAM_NONE;
122
 
        }
123
 
        return EN50221_STDCAM_CAM_OK;
124
 
}
125
 
 
126
 
 
127
 
 
128
 
static int hlci_cam_added(struct en50221_stdcam_hlci *hlci)
129
 
{
130
 
        uint8_t buf[256];
131
 
        int size;
132
 
 
133
 
        // get application information
134
 
        if (en50221_app_ai_enquiry(hlci->stdcam.ai_resource, 0)) {
135
 
                return -EIO;
136
 
        }
137
 
        if ((size = dvbca_hlci_read(hlci->cafd, TAG_APP_INFO, buf, sizeof(buf))) < 0) {
138
 
                return size;
139
 
        }
140
 
        if (en50221_app_ai_message(hlci->stdcam.ai_resource, 0, 0, EN50221_APP_AI_RESOURCEID, buf, size)) {
141
 
                return -EIO;
142
 
        }
143
 
 
144
 
        // we forge a fake CA_INFO here so the main app works - since it will expect a CA_INFO
145
 
        // this will be replaced with a proper call (below) when the driver support is there
146
 
        buf[0] = TAG_CA_INFO >> 16;
147
 
        buf[1] = (uint8_t) (TAG_CA_INFO >> 8);
148
 
        buf[2] = (uint8_t) TAG_CA_INFO;
149
 
        buf[3] = 0;
150
 
        if (en50221_app_ca_message(hlci->stdcam.ca_resource, 0, 0, EN50221_APP_CA_RESOURCEID, buf, 4)) {
151
 
                return -EIO;
152
 
        }
153
 
 
154
 
        /*
155
 
        // get CA information
156
 
           if (en50221_app_ca_info_enq(ca_resource, 0)) {
157
 
           fprintf(stderr, "Failed to send CA INFO enquiry\n");
158
 
           cafd = -1;
159
 
           return -1;
160
 
           }
161
 
           if ((size = dvbca_hlci_read(cafd, TAG_CA_INFO, buf, sizeof(buf))) < 0) {
162
 
           fprintf(stderr, "Failed to read CA INFO\n");
163
 
           cafd = -1;
164
 
           return -1;
165
 
           }
166
 
           if (en50221_app_ca_message(ca_resource, 0, 0, EN50221_APP_CA_RESOURCEID, buf, size)) {
167
 
           fprintf(stderr, "Failed to parse CA INFO\n");
168
 
           cafd = -1;
169
 
           return -1;
170
 
           }
171
 
         */
172
 
 
173
 
        // done
174
 
        hlci->initialised = 1;
175
 
        return 0;
176
 
}
177
 
 
178
 
static int hlci_send_data(void *arg, uint16_t session_number,
179
 
                          uint8_t * data, uint16_t data_length)
180
 
{
181
 
        (void) session_number;
182
 
        struct en50221_stdcam_hlci *hlci = arg;
183
 
 
184
 
        return dvbca_hlci_write(hlci->cafd, data, data_length);
185
 
}
186
 
 
187
 
static int hlci_send_datav(void *arg, uint16_t session_number,
188
 
                           struct iovec *vector, int iov_count)
189
 
{
190
 
        (void) session_number;
191
 
        struct en50221_stdcam_hlci *hlci = arg;
192
 
 
193
 
        // calculate the total length of the data to send
194
 
        uint32_t data_size = 0;
195
 
        int i;
196
 
        for (i = 0; i < iov_count; i++) {
197
 
                data_size += vector[i].iov_len;
198
 
        }
199
 
 
200
 
        // allocate memory for it
201
 
        uint8_t *buf = malloc(data_size);
202
 
        if (buf == NULL) {
203
 
                return -1;
204
 
        }
205
 
        // merge the iovecs
206
 
        uint32_t pos = 0;
207
 
        for (i = 0; i < iov_count; i++) {
208
 
                memcpy(buf + pos, vector[i].iov_base, vector[i].iov_len);
209
 
                pos += vector[i].iov_len;
210
 
        }
211
 
 
212
 
        // sendit and cleanup
213
 
        int status = dvbca_hlci_write(hlci->cafd, buf, data_size);
214
 
        free(buf);
215
 
        return status;
216
 
}