Updated Dnsmasq to 2.42 (#3498)
[openwrt.git] / package / fonera-mp3 / src / mp3_main.c
1 /*
2 * FOXMP3 
3 * Copyright (c) 2006 acmesystems.it - john@acmesystems.it
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA02111-1307USA
18 *
19 * Feedback, Bugs...  info@acmesystems.it 
20 *
21 */ 
22
23 #include <stdio.h>
24 #include <string.h>
25 #include <stdlib.h>
26 #include <unistd.h>
27 #include <sys/poll.h>
28 #include <signal.h>
29 #include "lib/mp3.h"
30
31 STATE states[MAX_STATE_COUNT];
32 static EVENT events[MAX_EVENT_COUNT];
33 static TRANSITION transitions[MAX_TRANSITION_COUNT];
34 static int transition_count = 0;
35 int state_current = MP3_STATE_STARTUP;
36 static int state_previous = MP3_STATE_NONE;
37 static int shutdown = 0;
38
39 void state_setup(void){
40         EVENT_ADD(MP3_EVENT_TIMEOUT, "Timeout");
41         EVENT_ADD(MP3_EVENT_FILE, "File");
42         EVENT_ADD(MP3_EVENT_STREAM, "Stream"); 
43         EVENT_ADD(MP3_EVENT_STOP, "Stop");
44         EVENT_ADD(MP3_EVENT_ERROR, "Error");
45         EVENT_ADD(MP3_EVENT_SHUTDOWN, "Shutdown");
46         EVENT_ADD(MP3_EVENT_END, "End");
47
48         STATE_ADD(MP3_STATE_STARTUP, "Startup", state_startup_enter, NULL);
49         STATE_ADD(MP3_STATE_IDLE, "Idle", state_idle_enter, NULL);
50         STATE_ADD(MP3_STATE_FILE_START, "File startup", state_file_startup_enter, state_file_startup_leave);
51         STATE_ADD(MP3_STATE_FILE_HANDLE, "File handle", state_file_handle_enter, state_file_handle_leave);
52         STATE_ADD(MP3_STATE_STREAM_START, "Stream start", state_stream_startup_enter, state_stream_startup_leave);
53         STATE_ADD(MP3_STATE_STREAM_HANDLE, "Stream handle", state_stream_handle_enter, state_stream_handle_leave);
54         STATE_ADD(MP3_STATE_ERROR, "Error", state_error_enter, NULL);
55         STATE_ADD(MP3_STATE_SHUTDOWN, "Shutdown", state_shutdown_enter, NULL);
56
57         TRANSITION_ADD(MP3_STATE_STARTUP, MP3_EVENT_TIMEOUT, MP3_STATE_IDLE);
58         
59         TRANSITION_ADD(MP3_STATE_IDLE, MP3_EVENT_TIMEOUT, MP3_STATE_IDLE);
60         TRANSITION_ADD(MP3_STATE_IDLE, MP3_EVENT_FILE, MP3_STATE_FILE_START);
61         TRANSITION_ADD(MP3_STATE_IDLE, MP3_EVENT_STREAM, MP3_STATE_STREAM_START);
62         
63         TRANSITION_ADD(MP3_STATE_FILE_START, MP3_EVENT_TIMEOUT, MP3_STATE_FILE_HANDLE);
64         TRANSITION_ADD(MP3_STATE_FILE_START, MP3_EVENT_ERROR, MP3_STATE_ERROR);
65
66         TRANSITION_ADD(MP3_STATE_FILE_HANDLE, MP3_EVENT_TIMEOUT, MP3_STATE_FILE_HANDLE);
67         TRANSITION_ADD(MP3_STATE_FILE_HANDLE, MP3_EVENT_END, MP3_STATE_IDLE);
68         TRANSITION_ADD(MP3_STATE_FILE_HANDLE, MP3_EVENT_ERROR, MP3_STATE_ERROR);
69         TRANSITION_ADD(MP3_STATE_FILE_HANDLE, MP3_EVENT_FILE, MP3_STATE_FILE_START);
70         TRANSITION_ADD(MP3_STATE_FILE_HANDLE, MP3_EVENT_STOP, MP3_STATE_IDLE);
71         TRANSITION_ADD(MP3_STATE_FILE_HANDLE, MP3_EVENT_STREAM, MP3_STATE_STREAM_START);
72
73         TRANSITION_ADD(MP3_STATE_STREAM_START, MP3_EVENT_TIMEOUT, MP3_STATE_STREAM_HANDLE);
74         TRANSITION_ADD(MP3_STATE_STREAM_START, MP3_EVENT_ERROR, MP3_STATE_ERROR);
75
76         TRANSITION_ADD(MP3_STATE_STREAM_HANDLE, MP3_EVENT_TIMEOUT, MP3_STATE_STREAM_HANDLE);
77         TRANSITION_ADD(MP3_STATE_STREAM_HANDLE, MP3_EVENT_STOP, MP3_STATE_IDLE);
78         TRANSITION_ADD(MP3_STATE_STREAM_HANDLE, MP3_EVENT_ERROR, MP3_STATE_ERROR);
79         TRANSITION_ADD(MP3_STATE_STREAM_HANDLE, MP3_EVENT_FILE, MP3_STATE_FILE_START);
80         TRANSITION_ADD(MP3_STATE_STREAM_HANDLE, MP3_EVENT_STREAM, MP3_STATE_STREAM_START);
81         
82         TRANSITION_ADD(MP3_STATE_ERROR, MP3_EVENT_TIMEOUT, MP3_STATE_IDLE);
83
84         TRANSITION_ADD(MP3_STATE_DEFAULT, MP3_EVENT_ERROR, MP3_STATE_ERROR);
85         TRANSITION_ADD(MP3_STATE_DEFAULT, MP3_EVENT_SHUTDOWN, MP3_STATE_SHUTDOWN);
86         state_startup_enter(0, 0, NULL);
87 };
88
89 void state_transition(int transition, int event, EVENT_PARAM *param){
90         state_previous = state_current;
91         state_current = transitions[transition].new_state;
92         if(state_previous != state_current){
93                 printf("\n -- Transition %s -> %s\n", 
94                         states[state_previous].name, 
95                         states[state_current].name);
96         };
97         if(states[state_previous].leave != NULL)
98                         states[state_previous].leave(state_current, event);
99         if(states[state_current].enter != NULL)
100                 states[state_current].enter(state_previous, event, param);
101         if(param){
102                 if(param->text){
103                         free(param->text);
104                 };
105                 free(param);
106         };
107 };
108
109 void state_event(int event, EVENT_PARAM *param){
110         int i = 0;
111         if(event != MP3_EVENT_TIMEOUT){
112                 printf("\n -- Got event %s (%d) in state %s (%d)\n", 
113                         events[event].name, 
114                         event, 
115                         states[state_current].name, 
116                         state_current);
117         };
118         for(i = 0; i < transition_count; i++){
119                 if((transitions[i].old_state == state_current) 
120                                 && (transitions[i].event == event)){
121                         state_transition(i, event, param);                      
122                         return;
123                 };
124         };
125         for(i = 0; i < transition_count; i++){
126                 if((transitions[i].old_state == MP3_STATE_DEFAULT) 
127                                 && (transitions[i].event == event)){
128                         state_transition(i, event, param);                      
129                         return;
130                 };
131         };
132         if(param){
133                 if(param->text){
134                         free(param->text);
135                 };
136                 free(param);
137         };
138         printf("Event %s not handled in state %s\n", events[event].name, states[state_current].name);
139 };
140
141 void state_mainloop(void){
142         while(1){
143                 if(shutdown){
144                         state_event(MP3_EVENT_SHUTDOWN, NULL);
145                 };
146                 mp3_nix_socket_handle();
147                 mp3_tcp_socket_handle();
148                 if(state_current == MP3_STATE_IDLE){
149                         poll(0, 0, 200);
150                 } else {
151                         poll(0, 0, 1);
152                 };
153                 state_event(MP3_EVENT_TIMEOUT, NULL);
154         };
155 };
156
157 EVENT_PARAM* state_new_event(unsigned char *text, int numeric){
158         EVENT_PARAM *p = (EVENT_PARAM*)malloc(sizeof(EVENT_PARAM));
159         if(text){
160                 p->text = strdup(text);
161         } else {
162                 p->text = NULL;
163         };
164         p->numeric = numeric;
165         return p;
166 };
167
168 void sig_handler(int sig){
169         shutdown = 1;
170 };
171
172 int main(int argc, char **argv) {       
173         unsigned char daemonize = 1;
174
175         printf("\n\n");
176         printf("ALPMP3 - MP3 Statemachine v1.0\n");
177
178         if(argc > 1){
179                 if(!strcmp(argv[1], "--no-daemon")){
180                         daemonize = 0;
181                 } else {
182                         printf("I am now going to daemonize. If you want me to stay in ");
183                         printf("the foreground, add the parameter --no-daemon.\n");
184                 };
185         };
186         
187         if(daemonize){
188                 daemon(0, 0);
189                 printf("----------------------------------------\n\n");
190                 printf("Made by openwrt.org (blogic@openwrt.org)\n");
191                 printf("\n");
192         };
193
194         signal(SIGINT, sig_handler); 
195         
196         state_setup();
197         state_mainloop();
198
199         return 0;
200 }
201
202
203
204