1 /** \file apd.c \brief Associated prosedure description
2 *
3 * $Author: peltotal $ $Date: 2007/02/28 08:58:00 $ $Revision: 1.14 $
4 *
5 * MAD-FLUTELIB: Implementation of FLUTE protocol.
6 * Copyright (c) 2003-2007 TUT - Tampere University of Technology
7 * main authors/contacts: jani.peltotalo@tut.fi and sami.peltotalo@tut.fi
8 *
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License as published by
11 * the Free Software Foundation; either version 2 of the License, or
12 * (at your option) any later version.
13 *
14 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
18 *
19 * You should have received a copy of the GNU General Public License
20 * along with this program; if not, write to the Free Software
21 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
22 *
23 * In addition, as a special exception, TUT - Tampere University of Technology
24 * gives permission to link the code of this program with the OpenSSL library (or
25 * with modified versions of OpenSSL that use the same license as OpenSSL), and
26 * distribute linked combinations including the two. You must obey the GNU
27 * General Public License in all respects for all of the code used other than
28 * OpenSSL. If you modify this file, you may extend this exception to your version
29 * of the file, but you are not obligated to do so. If you do not wish to do so,
30 * delete this exception statement from your version.
31 */
32
33 #include <stdlib.h>
34 #include <stdio.h>
35 #include <string.h>
36
37 #include <expat.h>
38
39 #include "apd.h"
40
41 #ifdef USE_FILE_REPAIR
42
43 /**
44 * Global variable used in parsing
45 */
46
47 apd_t *apd;
48
49 /**
50 * This is a private function which is used in parsing.
51 *
52 * @param userData used to carry element name to characterDataHandler function
53 * @param name pointer to buffer containing element's name
54 * @param atts pointer to buffer containing element's attributes
55 *
56 */
57
startElementHandler_APD(void * userData,const char * name,const char ** atts)58 static void startElementHandler_APD(void *userData, const char *name, const char **atts) {
59
60 strcpy((char*)userData, name);
61
62 while(*atts != NULL) {
63
64 if(!strcmp(name, "postFileRepair")) {
65
66 if(apd->postFileRepair == NULL) {
67
68 if(!(apd->postFileRepair = (postFileRepair_t*)calloc(1, sizeof(postFileRepair_t)))) {
69 printf("Could not alloc memory for postFileRepair!\n");
70 return;
71 }
72
73 /* initialise */
74
75 apd->postFileRepair->offsetTime = 0;
76 apd->postFileRepair->randomTimePeriod = 0;
77 apd->postFileRepair->serviceURI_List = NULL;
78 }
79
80 if(!strcmp(*atts, "offsetTime")) {
81
82 apd->postFileRepair->offsetTime = atoi(*(++atts));
83 }
84 else if(!strcmp(*atts, "randomTimePeriod")) {
85
86 apd->postFileRepair->randomTimePeriod = atoi(*(++atts));
87 }
88 }
89
90 else if(!strcmp(name, "bmFileRepair")) {
91
92 if(apd->bmFileRepair == NULL) {
93
94 if(!(apd->bmFileRepair = (bmFileRepair_t*)calloc(1, sizeof(bmFileRepair_t)))) {
95 printf("Could not alloc memory for bmFileRepair!\n");
96 return;
97 }
98
99 /* initialise */
100
101 strcpy(apd->bmFileRepair->sessionDescriptionURI, "");
102
103 }
104
105 if(!strcmp(*atts, "sessionDescriptionURI")) {
106
107 strcpy(apd->bmFileRepair->sessionDescriptionURI, *(++atts));
108 }
109 }
110
111 /* attribute in unknown element */
112
113 else {
114 atts ++;
115 }
116
117 atts++;
118
119 }
120 }
121
122 /**
123 * This is a private function which is used in parsing.
124 *
125 * @param userData must be, not used
126 * @param name pointer to buffer containing element's name
127 *
128 */
129
endElementHandler_APD(void * userData,const char * name)130 static void endElementHandler_APD(void *userData, const char *name) {
131
132 /* Let's remove the last element name from the userData */
133 strcpy((char*)userData, "");
134 }
135
136 /**
137 * This is a private function which is used in parsing.
138 *
139 * @param userData used to check in what element we are
140 * @param s pointer to buffer containing character data (s is not 0 terminated)
141 * @param len character data length
142 *
143 */
144
characterDataHandler_APD(void * userData,const XML_Char * s,int len)145 static void characterDataHandler_APD(void *userData, const XML_Char *s, int len) {
146
147 serviceURI_t *tmp_serviceURI;
148 serviceURI_t *serviceURI;
149 char *value;
150
151 value = (char*)calloc(len+1, sizeof(char));
152 memcpy(value, s, len);
153
154 /* userData includes the element (tag) name if we are inside some element */
155
156 if(strcmp((const char*)userData, "") == 0) {
157
158 }
159 else if(strcmp((const char*)userData, "serviceURI") == 0) {
160
161 if(!(serviceURI = (serviceURI_t*)calloc(1, sizeof(serviceURI_t)))) {
162 printf("Could not alloc memory for serviceURI!\n");
163 return;
164 }
165
166 strcpy(serviceURI->URI, value);
167 serviceURI->prev = NULL;
168 serviceURI->next = NULL;
169
170 tmp_serviceURI = apd->postFileRepair->serviceURI_List;
171
172 while(1) {
173
174 if(tmp_serviceURI == NULL) {
175 apd->postFileRepair->serviceURI_List = serviceURI;
176 break;
177 }
178
179 if(tmp_serviceURI->next == NULL) {
180 serviceURI->prev = tmp_serviceURI;
181 tmp_serviceURI->next = serviceURI;
182 break;
183 }
184
185 tmp_serviceURI = tmp_serviceURI->next;
186 }
187 }
188
189 free(value);
190 }
191
decode_apd_config(char * apd_config)192 apd_t* decode_apd_config(char *apd_config) {
193
194 XML_Parser parser = XML_ParserCreate(NULL);
195 size_t len;
196 char tag[100];
197
198 len = strlen(apd_config);
199
200 if(!(apd = (apd_t*)calloc(1, sizeof(apd_t)))) {
201 printf("Could not alloc memory for apd!\n");
202 XML_ParserFree(parser);
203 return NULL;
204 }
205
206 XML_SetUserData(parser, tag);
207 XML_SetStartElementHandler(parser, startElementHandler_APD);
208 XML_SetEndElementHandler(parser, endElementHandler_APD);
209 XML_SetCharacterDataHandler(parser, characterDataHandler_APD);
210
211 if(XML_Parse(parser, apd_config, len, 1) == XML_STATUS_ERROR) {
212 fprintf(stderr, "%s at line %d\n",
213 XML_ErrorString(XML_GetErrorCode(parser)),
214 XML_GetCurrentLineNumber(parser));
215 XML_ParserFree(parser);
216 return NULL;
217 }
218
219 XML_ParserFree(parser);
220
221 return apd;
222 }
223
FreeAPD(apd_t * apd)224 void FreeAPD(apd_t *apd) {
225
226 serviceURI_t *tmp_serviceURI;
227
228 if(apd->postFileRepair != NULL) {
229
230 while(1) {
231
232 tmp_serviceURI = apd->postFileRepair->serviceURI_List;
233
234 if(tmp_serviceURI != NULL) {
235 apd->postFileRepair->serviceURI_List = tmp_serviceURI->next;
236 free(tmp_serviceURI);
237 }
238 else {
239 break;
240 }
241 }
242
243 free(apd->postFileRepair);
244 }
245
246 if(apd->bmFileRepair != NULL) {
247 free(apd->bmFileRepair);
248 }
249
250 free(apd);
251 }
252
253 #endif
254
255