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