Statistics
| Revision:

root / logic / trunk / src / hci_comm / hci_comm_listener.c @ 57

History | View | Annotate | Download (8.77 KB)

1
/*
2
 * hci_comm_listener.c
3
 *
4
 * 2011, Aleksander Besir (alex.besir@gmail.com)
5
 *
6
 */
7

    
8
#include "hci_comm.h"
9
#include <sys/types.h>
10
#include <sys/socket.h>
11
#include <netinet/in.h>
12
#include <arpa/inet.h>
13
#include <stdio.h>
14
#include <stdlib.h>
15
#include <string.h>
16
#include <unistd.h>
17
#include "../mxml/mxml.h"
18
#include "hciChanged.h"
19

    
20
// Global variables from startup/main.c
21
    extern pthread_mutex_t mtx;
22
    extern int hciChanged;
23

    
24
int listenTo(unsigned short int portNum) {
25

    
26
    // Holders
27
    char *attrVal;
28
    char *name;
29
    int responseLength;
30

    
31
        // Buffer
32
        char *requestBuffer = malloc(HCI_COMM_REQUEST_BUFFER_SIZE * sizeof(char));
33
        if(requestBuffer == NULL) {
34
                printf("HCI comm error: Cannot allocate buffer.\n");
35
                return HCI_COMM_ERR_BUF_ALOC_FAIL;
36
        }
37
        char *responseBuffer = malloc(HCI_COMM_RESPONSE_BUFFER_SIZE * sizeof(char));
38
        if(responseBuffer == NULL) {
39
                printf("HCI comm error: Cannot allocate buffer.\n");
40
                return HCI_COMM_ERR_BUF_ALOC_FAIL;
41
        }
42
        char *lineBuffer = malloc(HCI_COMM_LINE_BUFFER_SIZE * sizeof(char));
43
        if(lineBuffer == NULL) {
44
                printf("HCI comm error: Cannot allocate buffer.\n");
45
                return HCI_COMM_ERR_BUF_ALOC_FAIL;
46
        }
47

    
48
        // Socket holder
49
        int socketHolder = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP);
50
        if(socketHolder < 0) {
51
                fprintf(stderr,"HCI comm error: Cannot create a new socket.\n");
52
                return HCI_COMM_ERR_NEW_SOCKET_FAIL;
53
        }
54

    
55
        // Socket address holder
56
        struct sockaddr_in socketAddressHolder;
57
        memset(&socketAddressHolder, 0, sizeof(socketAddressHolder));
58
        socketAddressHolder.sin_family      = AF_INET;
59
            socketAddressHolder.sin_port        = htons(portNum);
60
            socketAddressHolder.sin_addr.s_addr = INADDR_ANY;
61

    
62
        // Bind socket to port
63
        int bindingResult = bind(socketHolder,(struct sockaddr *)&socketAddressHolder, sizeof(socketAddressHolder));
64
        if(bindingResult == -1) {
65
                fprintf(stderr,"HCI comm error: Cannot bind socket to port %d.\n",portNum);
66
                close(socketHolder);
67
                return HCI_COMM_ERR_BIND_FAIL;
68
        }
69

    
70
        // Listen to port
71
        int listenResult = listen(socketHolder, 10);
72
        if(listenResult == -1) {
73
                printf("HCI comm error: Cannot listen to port %d.\n",portNum);
74
                close(socketHolder);
75
                return HCI_COMM_ERR_LISTEN_FAIL;
76
        }
77

    
78
        // Infinite listening
79
        while(1) {
80

    
81
        memset(responseBuffer,'\0',HCI_COMM_RESPONSE_BUFFER_SIZE);
82
        memset(requestBuffer,'\0',HCI_COMM_REQUEST_BUFFER_SIZE);
83
        memset(lineBuffer,'\0',HCI_COMM_LINE_BUFFER_SIZE);
84
        responseLength = 0;
85

    
86
            printf("[hci_comm_listener] Waiting for new connection...\n");
87

    
88
                // Accept request
89
                int connectionHolder = accept(socketHolder,NULL,NULL);
90
                if(connectionHolder < 0) {
91
                        printf("HCI comm error: Error accepting request.\n");
92
            shutdown(connectionHolder,SHUT_RDWR);
93
            close(connectionHolder);
94
            continue;
95
                }
96

    
97
                printf("[hci_comm_listener] New connection accepted\n");
98

    
99
                // Read request
100
                int readResult = read(connectionHolder,requestBuffer,HCI_COMM_REQUEST_BUFFER_SIZE);
101
                printf("[hci_comm_listener] Recieved request: %s \n",requestBuffer);
102
                if(readResult < 0) {
103
                        printf("HCI comm error: Error reading request.\n");
104
            strcpy(responseBuffer,"<logic-response type=\"error\">Could not read request!</logic-response>");
105
            responseLength = strlen(responseBuffer);
106
            write(connectionHolder,responseBuffer,responseLength);
107
            shutdown(connectionHolder,SHUT_RDWR);
108
            close(connectionHolder);
109
            continue;
110
                }
111

    
112
        // Parse request
113
        mxml_node_t *tree;
114
        tree = mxmlLoadString(NULL, requestBuffer, MXML_NO_CALLBACK);
115
        if(tree == NULL) {
116
            printf("[hci_comm_listener] Error parsing request!\n");
117
            strcpy(responseBuffer,"<logic-response type=\"error\">Could not parse request!</logic-response>");
118
            responseLength = strlen(responseBuffer);
119
            write(connectionHolder,responseBuffer,responseLength);
120
            shutdown(connectionHolder,SHUT_RDWR);
121
            close(connectionHolder);
122
            continue;
123
        }
124
        printf("[hci_comm_listener] Request parsed\n");
125

    
126
                // Create a response
127
                printf("[hci_comm_listener] Creating response\n");
128
                mxml_node_t *node;
129
        node = mxmlFindElement(tree, tree, "hci-request", NULL, NULL, MXML_DESCEND);
130
        if(node == NULL) {
131
            printf("[hci_comm_listener] Request invalid! Sending error to client\n");
132
            strcpy(responseBuffer,"<logic-response type=\"error\">Invalid request!</logic-response>");
133
            responseLength = strlen(responseBuffer);
134
            write(connectionHolder,responseBuffer,responseLength);
135
            shutdown(connectionHolder,SHUT_RDWR);
136
            close(connectionHolder);
137
            continue;
138
        }
139
        printf("[hci_comm_listener] Main request node found\n");
140
        printf("[hci_comm_listener] %d\n",node);
141

    
142
        attrVal = (char *)malloc(sizeof(node->value.element.attrs->value)*strlen(mxmlElementGetAttr(node, "type")));
143
        attrVal = mxmlElementGetAttr(node,"type");
144
        printf("[hci_comm_listener] Got type\n");
145
        if(strcmp(attrVal,"checkConnection") == 0) {
146
            printf("[hci_comm_listener] checkConnection request\n");
147
            strcpy(responseBuffer,"");
148
            strcat(responseBuffer,"<logic-response type=\"checkConnection\"><data>");
149
            mxml_node_t *child = node->child;
150
            child = child->child;
151
            strcat(responseBuffer,child->value.text.string);
152
            strcat(responseBuffer,"</data></logic-response>");
153
            printf("[hci_comm_listener] Response formed: %s\n",responseBuffer);
154
            responseLength = strlen(responseBuffer);
155
            printf("[hci_comm_listener] Response length formed: %d\n",responseLength);
156
        } else if(strcmp(attrVal,"getConfig") == 0) {
157
            printf("[hci_comm_listener] getConfig request\n");
158
            // TODO
159
        } else if(strcmp(attrVal,"setConfig") == 0) {
160
            printf("[hci_comm_listener] setConfig request\n");
161
            // TODO
162
        } else if(strcmp(attrVal,"getScenarios") == 0) {
163
            printf("[hci_comm_listener] getScenarios request\n");
164
            FILE *fp;
165
            if(fp = fopen("./scenariotree.xml", "r")) {
166
                printf("[hci_comm_listener] File opened\n");
167
                strcat(responseBuffer,"<logic-response type=\"getScenarios\">");
168
                while(fgets(lineBuffer,HCI_COMM_LINE_BUFFER_SIZE,fp)) {
169
                    strcat(responseBuffer,lineBuffer);
170
                }
171
                strcat(responseBuffer,"</logic-response>");
172
                responseLength = strlen(responseBuffer);
173
                fclose(fp);
174
            } else {
175
                 printf("[hci_comm_listener] Error: Can't open file scenariotree.xml\n");
176
                 strcpy(responseBuffer,"<logic-response type=\"error\">Could not read file!</logic-response>");
177
                 responseLength = strlen(responseBuffer);
178
            }
179
        } else if(strcmp(attrVal,"setScenarios") == 0) {
180
            printf("[hci_comm_listener] setScenarios request\n");
181
            // Prepare new content for scenariotree.xml
182
            strncpy(lineBuffer,requestBuffer+54,strlen(requestBuffer)-(54+14+2));
183
            strcpy(requestBuffer,"<?xml version=\"1.0\"?>");
184
            strcat(requestBuffer,lineBuffer);
185
            FILE *fp;
186
            if(fp = fopen("./scenariotree.xml", "w")) {
187
                fputs(requestBuffer,fp);
188
                fclose(fp);
189
                pthread_mutex_lock(&mtx);
190
                hciChanged = HCI_CHANGED_SCENARIOS;
191
                pthread_mutex_unlock(&mtx);
192
                strcpy(responseBuffer,"<logic-response type=\"setScenarios\"></logic-response>");
193
                responseLength = strlen(responseBuffer);
194
            } else {
195
                printf("[hci_comm_listener] Error: Can't open file scenariotree.xml for writing\n");
196
                strcpy(responseBuffer,"<logic-response type=\"error\">Could not write file!</logic-response>");
197
                responseLength = strlen(responseBuffer);
198
            }
199
        } else if(strcmp(attrVal,"executeAction") == 0) {
200
            printf("[hci_comm_listener] executeAction request\n");
201
            // TODO
202
        } else {
203
            strcpy(responseBuffer,"<logic-response type=\"error\">Invalid request!</logic-response>");
204
            responseLength = 62;
205
        }
206

    
207
                // Check if logic wants to terminate the infinite loop
208
                if(responseLength == HCI_COMM_TERMINATE) {
209
                        break;
210
                }
211

    
212
                // Send response
213
                int writeResult = write(connectionHolder,responseBuffer,responseLength);
214
                printf("[hci_comm_listener] Written response to client\n");
215
                if(writeResult < 0) {
216
                        printf("HCI comm error: Error writting response.\n");
217
                }
218

    
219
                // Close connection
220
                free(attrVal);
221
                shutdown(connectionHolder,SHUT_RDWR);
222
                close(connectionHolder);
223

    
224
                printf("[hci_comm_listener] Connection closed\n");
225

    
226
        }
227

    
228
        // Terminate
229
        close(socketHolder);
230
        free(requestBuffer);
231
        requestBuffer = NULL;
232
        return HCI_COMM_TERMINATED_BY_LOGIC;
233

    
234
}