Statistics
| Revision:

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

History | View | Annotate | Download (8.77 KB)

1 10 Janez1
/*
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 51 alexbesir
#include "../mxml/mxml.h"
18 57 alexbesir
#include "hciChanged.h"
19 10 Janez1
20 57 alexbesir
// Global variables from startup/main.c
21
    extern pthread_mutex_t mtx;
22
    extern int hciChanged;
23
24 10 Janez1
int listenTo(unsigned short int portNum) {
25
26 51 alexbesir
    // Holders
27 53 alexbesir
    char *attrVal;
28
    char *name;
29 54 alexbesir
    int responseLength;
30 51 alexbesir
31 10 Janez1
        // Buffer
32
        char *requestBuffer = malloc(HCI_COMM_REQUEST_BUFFER_SIZE * sizeof(char));
33
        if(requestBuffer == NULL) {
34 53 alexbesir
                printf("HCI comm error: Cannot allocate buffer.\n");
35 10 Janez1
                return HCI_COMM_ERR_BUF_ALOC_FAIL;
36
        }
37 53 alexbesir
        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 57 alexbesir
        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 10 Janez1
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 53 alexbesir
                printf("HCI comm error: Cannot listen to port %d.\n",portNum);
74 10 Janez1
                close(socketHolder);
75
                return HCI_COMM_ERR_LISTEN_FAIL;
76
        }
77
78
        // Infinite listening
79
        while(1) {
80
81 57 alexbesir
        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 53 alexbesir
            printf("[hci_comm_listener] Waiting for new connection...\n");
87
88 10 Janez1
                // Accept request
89
                int connectionHolder = accept(socketHolder,NULL,NULL);
90
                if(connectionHolder < 0) {
91 53 alexbesir
                        printf("HCI comm error: Error accepting request.\n");
92 54 alexbesir
            shutdown(connectionHolder,SHUT_RDWR);
93
            close(connectionHolder);
94
            continue;
95 10 Janez1
                }
96
97 53 alexbesir
                printf("[hci_comm_listener] New connection accepted\n");
98
99 10 Janez1
                // Read request
100
                int readResult = read(connectionHolder,requestBuffer,HCI_COMM_REQUEST_BUFFER_SIZE);
101 53 alexbesir
                printf("[hci_comm_listener] Recieved request: %s \n",requestBuffer);
102 10 Janez1
                if(readResult < 0) {
103 53 alexbesir
                        printf("HCI comm error: Error reading request.\n");
104 54 alexbesir
            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 10 Janez1
                }
111
112 51 alexbesir
        // Parse request
113
        mxml_node_t *tree;
114 53 alexbesir
        tree = mxmlLoadString(NULL, requestBuffer, MXML_NO_CALLBACK);
115
        if(tree == NULL) {
116
            printf("[hci_comm_listener] Error parsing request!\n");
117 54 alexbesir
            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 53 alexbesir
        }
124
        printf("[hci_comm_listener] Request parsed\n");
125 51 alexbesir
126 10 Janez1
                // Create a response
127 53 alexbesir
                printf("[hci_comm_listener] Creating response\n");
128 51 alexbesir
                mxml_node_t *node;
129 53 alexbesir
        node = mxmlFindElement(tree, tree, "hci-request", NULL, NULL, MXML_DESCEND);
130
        if(node == NULL) {
131 54 alexbesir
            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 53 alexbesir
        }
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 51 alexbesir
        if(strcmp(attrVal,"checkConnection") == 0) {
146 53 alexbesir
            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 51 alexbesir
        } else if(strcmp(attrVal,"getConfig") == 0) {
157 57 alexbesir
            printf("[hci_comm_listener] getConfig request\n");
158 51 alexbesir
            // TODO
159
        } else if(strcmp(attrVal,"setConfig") == 0) {
160 57 alexbesir
            printf("[hci_comm_listener] setConfig request\n");
161 51 alexbesir
            // TODO
162
        } else if(strcmp(attrVal,"getScenarios") == 0) {
163 57 alexbesir
            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 51 alexbesir
        } else if(strcmp(attrVal,"setScenarios") == 0) {
180 57 alexbesir
            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 51 alexbesir
        } else if(strcmp(attrVal,"executeAction") == 0) {
200 57 alexbesir
            printf("[hci_comm_listener] executeAction request\n");
201 51 alexbesir
            // TODO
202
        } else {
203 53 alexbesir
            strcpy(responseBuffer,"<logic-response type=\"error\">Invalid request!</logic-response>");
204 51 alexbesir
            responseLength = 62;
205
        }
206 10 Janez1
207
                // Check if logic wants to terminate the infinite loop
208
                if(responseLength == HCI_COMM_TERMINATE) {
209
                        break;
210
                }
211
212
                // Send response
213 53 alexbesir
                int writeResult = write(connectionHolder,responseBuffer,responseLength);
214
                printf("[hci_comm_listener] Written response to client\n");
215 10 Janez1
                if(writeResult < 0) {
216 53 alexbesir
                        printf("HCI comm error: Error writting response.\n");
217 10 Janez1
                }
218
219 53 alexbesir
                // Close connection
220
                free(attrVal);
221
                shutdown(connectionHolder,SHUT_RDWR);
222
                close(connectionHolder);
223
224
                printf("[hci_comm_listener] Connection closed\n");
225
226 10 Janez1
        }
227
228
        // Terminate
229
        close(socketHolder);
230
        free(requestBuffer);
231
        requestBuffer = NULL;
232
        return HCI_COMM_TERMINATED_BY_LOGIC;
233
234
}