Statistics
| Branch: | Tag: | Revision:

mongoose / examples / PIC32 / http_server / firmware / src / app.c @ eaef5bd1

History | View | Annotate | Download (10.3 KB)

1
/* clang-format off */
2
/*******************************************************************************
3
  MPLAB Harmony Application Source File
4

5
  Company:
6
    Microchip Technology Inc.
7

8
  File Name:
9
    app.c
10

11
  Summary:
12
    This file contains the source code for the MPLAB Harmony application.
13

14
  Description:
15
    This file contains the source code for the MPLAB Harmony application.  It
16
    implements the logic of the application's state machine and it may call
17
    API routines of other MPLAB Harmony modules in the system, such as drivers,
18
    system services, and middleware.  However, it does not call any of the
19
    system interfaces (such as the "Initialize" and "Tasks" functions) of any of
20
    the modules in the system or make any assumptions about when those functions
21
    are called.  That is the responsibility of the configuration-specific system
22
    files.
23
 *******************************************************************************/
24

    
25
// DOM-IGNORE-BEGIN
26
/*******************************************************************************
27
Copyright (c) 2013-2014 released Microchip Technology Inc.  All rights reserved.
28

29
Microchip licenses to you the right to use, modify, copy and distribute
30
Software only when embedded on a Microchip microcontroller or digital signal
31
controller that is integrated into your product or third party product
32
(pursuant to the sublicense terms in the accompanying license agreement).
33

34
You should refer to the license agreement accompanying this Software for
35
additional information regarding your rights and obligations.
36

37
SOFTWARE AND DOCUMENTATION ARE PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND,
38
EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION, ANY WARRANTY OF
39
MERCHANTABILITY, TITLE, NON-INFRINGEMENT AND FITNESS FOR A PARTICULAR PURPOSE.
40
IN NO EVENT SHALL MICROCHIP OR ITS LICENSORS BE LIABLE OR OBLIGATED UNDER
41
CONTRACT, NEGLIGENCE, STRICT LIABILITY, CONTRIBUTION, BREACH OF WARRANTY, OR
42
OTHER LEGAL EQUITABLE THEORY ANY DIRECT OR INDIRECT DAMAGES OR EXPENSES
43
INCLUDING BUT NOT LIMITED TO ANY INCIDENTAL, SPECIAL, INDIRECT, PUNITIVE OR
44
CONSEQUENTIAL DAMAGES, LOST PROFITS OR LOST DATA, COST OF PROCUREMENT OF
45
SUBSTITUTE GOODS, TECHNOLOGY, SERVICES, OR ANY CLAIMS BY THIRD PARTIES
46
(INCLUDING BUT NOT LIMITED TO ANY DEFENSE THEREOF), OR OTHER SIMILAR COSTS.
47
 *******************************************************************************/
48
// DOM-IGNORE-END
49

    
50

    
51
// *****************************************************************************
52
// *****************************************************************************
53
// Section: Included Files
54
// *****************************************************************************
55
// *****************************************************************************
56

    
57
#include "app.h"
58
#include "./../../../../../mongoose.h"
59

    
60
// *****************************************************************************
61
// *****************************************************************************
62
// Section: Global Data Definitions
63
// *****************************************************************************
64
// *****************************************************************************
65

    
66
// *****************************************************************************
67
/* Application Data
68

69
  Summary:
70
    Holds application data
71

72
  Description:
73
    This structure holds the application's data.
74

75
  Remarks:
76
    This structure should be initialized by the APP_Initialize function.
77

78
    Application strings and buffers are be defined outside this structure.
79
*/
80

    
81
APP_DATA appData;
82
struct mg_mgr mgr;
83

    
84
// *****************************************************************************
85
// *****************************************************************************
86
// Section: Application Callback Functions
87
// *****************************************************************************
88
// *****************************************************************************
89

    
90
/* TODO:  Add any necessary callback funtions.
91
*/
92

    
93

    
94
// *****************************************************************************
95
// *****************************************************************************
96
// Section: Application Local Functions
97
// *****************************************************************************
98
// *****************************************************************************
99

    
100

    
101

    
102
// *****************************************************************************
103
// *****************************************************************************
104
// Section: Application Initialization and State Machine Functions
105
// *****************************************************************************
106
// *****************************************************************************
107

    
108
/*******************************************************************************
109
  Function:
110
    void APP_Initialize ( void )
111

112
  Remarks:
113
    See prototype in app.h.
114
 */
115

    
116
const char *s_http_port = "8000";
117

    
118
void ev_handler(struct mg_connection *nc, int ev, void *ev_data) {
119
 switch (ev) {
120
    case MG_EV_ACCEPT: {
121
      char addr[32];
122
      mg_sock_addr_to_str(&nc->sa, addr, sizeof(addr),
123
                          MG_SOCK_STRINGIFY_IP | MG_SOCK_STRINGIFY_PORT);
124
      SYS_PRINT("%p: Connection from %s\r\n", nc, addr);
125
      break;
126
    }
127
    case MG_EV_HTTP_REQUEST: {
128
      struct http_message *hm = (struct http_message *) ev_data;
129
      char addr[32];
130
      mg_sock_addr_to_str(&nc->sa, addr, sizeof(addr),
131
                          MG_SOCK_STRINGIFY_IP | MG_SOCK_STRINGIFY_PORT);
132
      SYS_PRINT("%p: %.*s %.*s\r\n", nc, (int) hm->method.len, hm->method.p,
133
             (int) hm->uri.len, hm->uri.p);
134
      mg_send_response_line(nc, 200,
135
                            "Content-Type: text/html\r\n"
136
                            "Connection: close");
137
      mg_printf(nc,
138
                "\r\n<h1>Hello, %s!</h1>\r\n"
139
                "You asked for %.*s\r\n",
140
                addr, (int) hm->uri.len, hm->uri.p);
141
      nc->flags |= MG_F_SEND_AND_CLOSE;
142
      break;
143
    }
144
    case MG_EV_CLOSE: {
145
      SYS_PRINT("%p: Connection closed\r\n", nc);
146
      break;
147
    }
148
  }
149
}
150

    
151
void APP_Initialize ( void )
152
{
153
    /* Place the App state machine in its initial state. */
154
    appData.state = APP_STATE_INIT;
155

    
156
    mg_mgr_init(&mgr, NULL);
157
}
158

    
159

    
160
/******************************************************************************
161
  Function:
162
    void APP_Tasks ( void )
163

164
  Remarks:
165
    See prototype in app.h.
166
 */
167

    
168
void APP_Tasks ( void )
169
{
170
    SYS_STATUS          tcpipStat;
171
    const char          *netName, *netBiosName;
172
    static IPV4_ADDR    dwLastIP[2] = { {-1}, {-1} };
173
    IPV4_ADDR           ipAddr;
174
    TCPIP_NET_HANDLE    netH;
175
    int                 i, nNets;
176

    
177
    /* Check the application's current state. */
178
    switch ( appData.state )
179
    {
180
        /* Application's initial state. */
181
        case APP_STATE_INIT:
182
        {
183
            tcpipStat = TCPIP_STACK_Status(sysObj.tcpip);
184
            if(tcpipStat < 0)
185
            {   // some error occurred
186
                SYS_CONSOLE_MESSAGE(" APP: TCP/IP stack initialization failed!\r\n");
187
                appData.state = APP_DONE;
188
            }
189
            else if(tcpipStat == SYS_STATUS_READY)
190
            {
191
                // now that the stack is ready we can check the
192
                // available interfaces
193
                nNets = TCPIP_STACK_NumberOfNetworksGet();
194
                for(i = 0; i < nNets; i++)
195
                {
196

    
197
                    netH = TCPIP_STACK_IndexToNet(i);
198
                    netName = TCPIP_STACK_NetNameGet(netH);
199
                    netBiosName = TCPIP_STACK_NetBIOSName(netH);
200

    
201
#if defined(TCPIP_STACK_USE_NBNS)
202
                    SYS_CONSOLE_PRINT("    Interface %s on host %s - NBNS enabled\r\n", netName, netBiosName);
203
#else
204
                    SYS_CONSOLE_PRINT("    Interface %s on host %s - NBNS disabled\r\n", netName, netBiosName);
205
#endif  // defined(TCPIP_STACK_USE_NBNS)
206

    
207
                }
208
                appData.state = APP_TCPIP_WAIT_FOR_IP;
209

    
210
            }
211
            break;
212
        }
213
        case APP_TCPIP_WAIT_FOR_IP:
214

    
215
            // if the IP address of an interface has changed
216
            // display the new value on the system console
217
            nNets = TCPIP_STACK_NumberOfNetworksGet();
218

    
219
            for (i = 0; i < nNets; i++)
220
            {
221
                netH = TCPIP_STACK_IndexToNet(i);
222
                ipAddr.Val = TCPIP_STACK_NetAddress(netH);
223
                if(dwLastIP[i].Val != ipAddr.Val)
224
                {
225
                    dwLastIP[i].Val = ipAddr.Val;
226

    
227
                    SYS_CONSOLE_MESSAGE(TCPIP_STACK_NetNameGet(netH));
228
                    SYS_CONSOLE_MESSAGE(" IP Address: ");
229
                    SYS_CONSOLE_PRINT("%d.%d.%d.%d \r\n", ipAddr.v[0], ipAddr.v[1], ipAddr.v[2], ipAddr.v[3]);
230
                    if (ipAddr.v[0] != 0 && ipAddr.v[0] != 169) // Wait for a Valid IP
231
                    {
232
                        appData.state = APP_START_LISTENING;
233
                    }
234
                }
235
            }
236
            break;
237
        case APP_START_LISTENING:
238
        {
239
            SYS_CONSOLE_PRINT("Starting listening on port 8000\r\n");
240
            struct mg_connection *nc = mg_bind(&mgr, "8000", ev_handler);  // Create listening connection and add it to the event manager
241
            if (nc == NULL) {
242
              SYS_CONSOLE_PRINT("Failed to create listener\n\r");
243
              appData.state = APP_DONE;
244
              break;
245
            }
246
            mg_set_protocol_http_websocket(nc);
247
            SYS_CONSOLE_PRINT("Listener started\r\n");
248

    
249
            appData.state = APP_POLL;
250
            break;
251
        }
252
        case APP_POLL:
253
        {
254
            mg_mgr_poll(&mgr, 1000);
255
            break;
256
        }
257
        case APP_DONE:
258
        {
259
            SYS_CONSOLE_PRINT("Server stopped\n\r");
260
            appData.state = APP_EMPTY;
261
            break;
262
        }
263
        case APP_EMPTY:
264
        {
265
            break;
266
        }
267
        /* The default state should never be executed. */
268
        default:
269
        {
270
            /* TODO: Handle error in application's state machine. */
271
            break;
272
        }
273
    }
274
}
275

    
276
/*******************************************************************************
277
 End of File
278
 */
279