mbed 5.4 with sleep mode

Dependencies:   C027_Support mbed-dev

Fork of C027_SupportTest_coap by Umar Naeem

Committer:
mazgch
Date:
Thu May 15 06:16:51 2014 +0000
Revision:
18:50e6c4ed8a4a
Parent:
17:c293780a40ac
Child:
19:f022ff746eb8
new lib

Who changed what in which revision?

UserRevisionLine numberNew contents of line
lawliet 0:4e3cb26f6019 1 #include "mbed.h"
mazgch 2:b77151f111a9 2 #include "GPS.h"
mazgch 2:b77151f111a9 3 #include "MDM.h"
lawliet 0:4e3cb26f6019 4
mazgch 9:26f694bc31b4 5 //----------------------------------------------------------------------
mazgch 9:26f694bc31b4 6 // You may need to configure these parameters
mazgch 9:26f694bc31b4 7
mazgch 9:26f694bc31b4 8 /** Set your secret SIM pin here "1234"
mazgch 9:26f694bc31b4 9 */
mazgch 9:26f694bc31b4 10 #define SIMPIN NULL
mazgch 9:26f694bc31b4 11
mazgch 9:26f694bc31b4 12 /** The APN of your network operator, sometimes it is "internet"
mazgch 9:26f694bc31b4 13 check your contract with the network operator
mazgch 9:26f694bc31b4 14 */
mazgch 9:26f694bc31b4 15 #define APN "gprs.swisscom.ch"
mazgch 9:26f694bc31b4 16
mazgch 9:26f694bc31b4 17 /** Set the user name for your APN, or NULL if not needed
mazgch 9:26f694bc31b4 18 */
mazgch 9:26f694bc31b4 19 #define USERNAME NULL
mazgch 9:26f694bc31b4 20
mazgch 9:26f694bc31b4 21 /** Set the password for your APN, or NULL if not needed
mazgch 9:26f694bc31b4 22 */
mazgch 9:26f694bc31b4 23 #define PASSWORD NULL
mazgch 9:26f694bc31b4 24
mazgch 10:d2da2028a233 25 //----------------------------------------------------------------------
mazgch 11:b8505cbbd55c 26 /* This example was tested on C027-U20 and C027-G35 with the on board modem.
mazgch 11:b8505cbbd55c 27
mazgch 18:50e6c4ed8a4a 28 Additionally it was tested with a shield where the SARA-G350/U260/U270 RX/TX/PWRON
mazgch 11:b8505cbbd55c 29 is connected to D0/D1/D4 and the GPS SCL/SDA is connected D15/D15. In this
mazgch 11:b8505cbbd55c 30 configuration the following platforms were tested (it is likely that others
mazgch 11:b8505cbbd55c 31 will work as well)
mazgch 18:50e6c4ed8a4a 32 - U-BLOX: C027-G35, C027-U20, C027-C20 (for shield remove define C027_USEONBOARD)
mazgch 18:50e6c4ed8a4a 33 - NXP: LPC1549v2, LPC4088qsb
mazgch 18:50e6c4ed8a4a 34 - Freescale: FRDM-KL05Z, FRDM-KL25Z, FRDM-KL46Z, FRDM-K64F
mazgch 12:96c7b62c7aaf 35 - STM: NUCLEO-F401RE, NUCLEO-F030R8
mazgch 18:50e6c4ed8a4a 36 mount resistors SB13/14 1k, SB62/63 0R
mazgch 11:b8505cbbd55c 37 */
mazgch 13:662bd1df9a72 38 #if defined(TARGET_UBLOX_C027)
mazgch 18:50e6c4ed8a4a 39 #define C027_USEONBOARD // remove if you have the GSM/GPS shield mounted to the C027
mazgch 10:d2da2028a233 40 #endif
mazgch 10:d2da2028a233 41
mazgch 13:662bd1df9a72 42 #ifdef C027_USEONBOARD
mazgch 13:662bd1df9a72 43 #include "C027.h"
mazgch 13:662bd1df9a72 44 C027 c027;
mazgch 18:50e6c4ed8a4a 45 #else
mazgch 10:d2da2028a233 46 #define GPSSCL D15
mazgch 10:d2da2028a233 47 #define GPSSDA D14
mazgch 10:d2da2028a233 48 #define GPSADR (66<<1) // GPS I2C Address
mazgch 10:d2da2028a233 49 #define MDMPWRON D4
mazgch 10:d2da2028a233 50 #define MDMTXD D1
mazgch 10:d2da2028a233 51 #define MDMRXD D0
mazgch 10:d2da2028a233 52 #define MDMCTS NC
mazgch 10:d2da2028a233 53 #define MDMRTS NC
mazgch 10:d2da2028a233 54 #define MDMBAUD 115200
mazgch 10:d2da2028a233 55 #endif
mazgch 10:d2da2028a233 56
mazgch 18:50e6c4ed8a4a 57 //----------------------------------------------------------------------
mazgch 10:d2da2028a233 58 // no tracing if serial is shared with the VCP
mazgch 15:ea10b6cf8c85 59 #define DOTRACE ((USBRX!=MDMRXD)&&(USBTX!=MDMTXD))
mazgch 15:ea10b6cf8c85 60 #define TRACE (!DOTRACE)?:printf
lawliet 0:4e3cb26f6019 61
lawliet 0:4e3cb26f6019 62 int main(void)
lawliet 0:4e3cb26f6019 63 {
mazgch 2:b77151f111a9 64 int ret;
mazgch 17:c293780a40ac 65 #ifdef TARGET_LPC1768
mazgch 16:43f6de7bc38b 66 char buf[2048] = "";
mazgch 17:c293780a40ac 67 #else
mazgch 17:c293780a40ac 68 char buf[512] = "";
mazgch 17:c293780a40ac 69 #endif
lawliet 0:4e3cb26f6019 70
mazgch 13:662bd1df9a72 71 // only trace if the serial is different from our modem port
mazgch 15:ea10b6cf8c85 72 if (DOTRACE) {
mazgch 11:b8505cbbd55c 73 Serial pc(USBTX,USBRX);
mazgch 11:b8505cbbd55c 74 pc.baud(115200);
mazgch 11:b8505cbbd55c 75 }
mazgch 11:b8505cbbd55c 76
mazgch 11:b8505cbbd55c 77 wait_ms(1000);
mazgch 2:b77151f111a9 78
mazgch 10:d2da2028a233 79 TRACE("GSM/GPS Support Example\r\n");
mazgch 11:b8505cbbd55c 80
mazgch 10:d2da2028a233 81 #ifdef C027_USEONBOARD
mazgch 10:d2da2028a233 82 // turn on the supplies of the Modem and the GPS
mazgch 2:b77151f111a9 83 c027.mdmPower(true);
mazgch 4:90ab1ec64b0e 84 c027.gpsPower(true);
mazgch 10:d2da2028a233 85 #else
mazgch 10:d2da2028a233 86 // turn on the Modem
mazgch 10:d2da2028a233 87 DigitalOut mdmPwrOn(MDMPWRON, 0);
mazgch 10:d2da2028a233 88 wait_ms(150);
mazgch 10:d2da2028a233 89 mdmPwrOn = 1;
mazgch 10:d2da2028a233 90 #endif
mazgch 2:b77151f111a9 91 wait(2);
mazgch 11:b8505cbbd55c 92
mazgch 10:d2da2028a233 93 // Create the GPS object
mazgch 13:662bd1df9a72 94 #if GPSADR // use GPSI2C class
mazgch 13:662bd1df9a72 95 GPSI2C gps(GPSSDA,GPSSCL,GPSADR);
mazgch 13:662bd1df9a72 96 #elif GPSBAUD // or GPSSerial class
mazgch 13:662bd1df9a72 97 GPSSerial gps(GPSTXD,GPSRXD,GPSBAUD);
mazgch 10:d2da2028a233 98 #else
mazgch 10:d2da2028a233 99 #warning "please define the pins for the GPS"
mazgch 10:d2da2028a233 100 #endif
mazgch 11:b8505cbbd55c 101
mazgch 10:d2da2028a233 102 // Create the modem object
mazgch 7:e000317ddef6 103 MDMSerial mdm(MDMTXD,MDMRXD,MDMBAUD
mazgch 10:d2da2028a233 104 #if DEVICE_SERIAL_FC
mazgch 7:e000317ddef6 105 ,MDMRTS,MDMCTS
mazgch 10:d2da2028a233 106 #endif
mazgch 2:b77151f111a9 107 );
mazgch 11:b8505cbbd55c 108
mazgch 2:b77151f111a9 109 // initialize the modem
mazgch 10:d2da2028a233 110 TRACE("Device Init\r\n");
mazgch 5:5366d39d3719 111 MDMParser::DevStatus devStatus;
mazgch 5:5366d39d3719 112 MDMParser::NetStatus netStatus;
mazgch 10:d2da2028a233 113 bool mdmOk = mdm.init(SIMPIN, &devStatus);
mazgch 10:d2da2028a233 114 if (mdmOk)
mazgch 4:90ab1ec64b0e 115 {
mazgch 15:ea10b6cf8c85 116 if (DOTRACE) mdm.dumpDevStatus(&devStatus);
mazgch 5:5366d39d3719 117
mazgch 4:90ab1ec64b0e 118 // wait until we are connected
mazgch 10:d2da2028a233 119 TRACE("Network Check\r\n");
mazgch 5:5366d39d3719 120 while (!mdm.checkNetStatus(&netStatus))
mazgch 4:90ab1ec64b0e 121 wait_ms(1000);
mazgch 2:b77151f111a9 122
mazgch 15:ea10b6cf8c85 123 if (DOTRACE) mdm.dumpNetStatus(&netStatus);
mazgch 10:d2da2028a233 124 TRACE("Network Join\r\n");
mazgch 4:90ab1ec64b0e 125 // join the internet connection
mazgch 5:5366d39d3719 126 MDMParser::IP ip =
mazgch 9:26f694bc31b4 127 mdm.join(APN,USERNAME,PASSWORD);
mazgch 5:5366d39d3719 128 if (ip != NOIP)
mazgch 2:b77151f111a9 129 {
mazgch 15:ea10b6cf8c85 130 if (DOTRACE) mdm.dumpIp(ip);
mazgch 10:d2da2028a233 131 TRACE("Socket Create\r\n");
mazgch 4:90ab1ec64b0e 132 int socket = mdm.socketSocket(MDMParser::IPPROTO_TCP);
mazgch 4:90ab1ec64b0e 133 if (socket >= 0)
mazgch 2:b77151f111a9 134 {
mazgch 10:d2da2028a233 135 TRACE("Socket Connect\r\n");
mazgch 16:43f6de7bc38b 136 mdm.socketSetBlocking(socket, 10000);
mazgch 4:90ab1ec64b0e 137 if (mdm.socketConnect(socket, "mbed.org", 80))
mazgch 4:90ab1ec64b0e 138 {
mazgch 10:d2da2028a233 139 TRACE("Make a Http Post Request\r\n");
mazgch 4:90ab1ec64b0e 140 const char http[] = "GET /media/uploads/mbed_official/hello.txt HTTP/1.0\r\n\r\n";
mazgch 10:d2da2028a233 141 TRACE("Socket Send\r\n");
mazgch 4:90ab1ec64b0e 142 mdm.socketSend(socket, http, sizeof(http)-1);
mazgch 4:90ab1ec64b0e 143
mazgch 10:d2da2028a233 144 TRACE("Socket Recving\r\n");
mazgch 4:90ab1ec64b0e 145 while (true) {
mazgch 4:90ab1ec64b0e 146 ret = mdm.socketReadable(socket);
mazgch 4:90ab1ec64b0e 147 if (ret > 0)
mazgch 4:90ab1ec64b0e 148 ret = mdm.socketRecv(socket, buf, sizeof(buf)-1);
mazgch 4:90ab1ec64b0e 149 if (ret < 0)
mazgch 4:90ab1ec64b0e 150 break;
mazgch 4:90ab1ec64b0e 151 else if (ret > 0)
mazgch 10:d2da2028a233 152 TRACE("Socket Recv \"%*s\"\r\n", ret, buf);
mazgch 4:90ab1ec64b0e 153 }
mazgch 10:d2da2028a233 154 TRACE("Socket Close\r\n");
mazgch 4:90ab1ec64b0e 155 mdm.socketClose(socket);
mazgch 4:90ab1ec64b0e 156 }
mazgch 10:d2da2028a233 157 TRACE("Socket Free\r\n");
mazgch 4:90ab1ec64b0e 158 mdm.socketFree(socket);
mazgch 4:90ab1ec64b0e 159 }
mazgch 2:b77151f111a9 160
mazgch 16:43f6de7bc38b 161 int port = 7;
mazgch 16:43f6de7bc38b 162 const char* host = "echo.u-blox.com";
mazgch 16:43f6de7bc38b 163 MDMParser::IP ip = mdm.gethostbyname(host);
mazgch 16:43f6de7bc38b 164 char data[] = "\r\nxxx Socket Hello World\r\n"
mazgch 17:c293780a40ac 165 #ifdef TARGET_LPC1768
mazgch 17:c293780a40ac 166 "00 0123456789 0123456789 0123456789 0123456789 0123456789 \r\n"
mazgch 17:c293780a40ac 167 "01 0123456789 0123456789 0123456789 0123456789 0123456789 \r\n"
mazgch 17:c293780a40ac 168 "02 0123456789 0123456789 0123456789 0123456789 0123456789 \r\n"
mazgch 17:c293780a40ac 169 "03 0123456789 0123456789 0123456789 0123456789 0123456789 \r\n"
mazgch 17:c293780a40ac 170 "04 0123456789 0123456789 0123456789 0123456789 0123456789 \r\n"
mazgch 17:c293780a40ac 171
mazgch 17:c293780a40ac 172 "05 0123456789 0123456789 0123456789 0123456789 0123456789 \r\n"
mazgch 17:c293780a40ac 173 "06 0123456789 0123456789 0123456789 0123456789 0123456789 \r\n"
mazgch 17:c293780a40ac 174 "07 0123456789 0123456789 0123456789 0123456789 0123456789 \r\n"
mazgch 17:c293780a40ac 175 "08 0123456789 0123456789 0123456789 0123456789 0123456789 \r\n"
mazgch 17:c293780a40ac 176 "09 0123456789 0123456789 0123456789 0123456789 0123456789 \r\n"
mazgch 16:43f6de7bc38b 177
mazgch 17:c293780a40ac 178 "10 0123456789 0123456789 0123456789 0123456789 0123456789 \r\n"
mazgch 17:c293780a40ac 179 "11 0123456789 0123456789 0123456789 0123456789 0123456789 \r\n"
mazgch 17:c293780a40ac 180 "12 0123456789 0123456789 0123456789 0123456789 0123456789 \r\n"
mazgch 17:c293780a40ac 181 "13 0123456789 0123456789 0123456789 0123456789 0123456789 \r\n"
mazgch 17:c293780a40ac 182 "14 0123456789 0123456789 0123456789 0123456789 0123456789 \r\n"
mazgch 17:c293780a40ac 183
mazgch 17:c293780a40ac 184 "15 0123456789 0123456789 0123456789 0123456789 0123456789 \r\n"
mazgch 17:c293780a40ac 185 "16 0123456789 0123456789 0123456789 0123456789 0123456789 \r\n"
mazgch 17:c293780a40ac 186 "17 0123456789 0123456789 0123456789 0123456789 0123456789 \r\n"
mazgch 17:c293780a40ac 187 "18 0123456789 0123456789 0123456789 0123456789 0123456789 \r\n"
mazgch 17:c293780a40ac 188 "19 0123456789 0123456789 0123456789 0123456789 0123456789 \r\n"
mazgch 16:43f6de7bc38b 189 #endif
mazgch 17:c293780a40ac 190 "End\r\n";
mazgch 16:43f6de7bc38b 191
mazgch 16:43f6de7bc38b 192 TRACE("Testing TCP sockets with ECHO server\r\n");
mazgch 16:43f6de7bc38b 193 socket = mdm.socketSocket(MDMParser::IPPROTO_TCP);
mazgch 16:43f6de7bc38b 194 if (socket >= 0)
mazgch 16:43f6de7bc38b 195 {
mazgch 16:43f6de7bc38b 196 mdm.socketSetBlocking(socket, 10000);
mazgch 16:43f6de7bc38b 197 if (mdm.socketConnect(socket, host, port)) {
mazgch 16:43f6de7bc38b 198 memcpy(data, "\r\nTCP", 5);
mazgch 16:43f6de7bc38b 199 ret = mdm.socketSend(socket, data, sizeof(data)-1);
mazgch 16:43f6de7bc38b 200 if (ret == sizeof(data)-1) {
mazgch 16:43f6de7bc38b 201 TRACE("Socket Send %d \"%s\"\r\n", ret, data);
mazgch 16:43f6de7bc38b 202 }
mazgch 16:43f6de7bc38b 203 ret = mdm.socketRecv(socket, buf, sizeof(buf)-1);
mazgch 16:43f6de7bc38b 204 if (ret >= 0) {
mazgch 16:43f6de7bc38b 205 TRACE("Socket Recv %d \"%.*s\"\r\n", ret, ret, buf);
mazgch 16:43f6de7bc38b 206 }
mazgch 16:43f6de7bc38b 207 mdm.socketClose(socket);
mazgch 16:43f6de7bc38b 208 }
mazgch 16:43f6de7bc38b 209 mdm.socketFree(socket);
mazgch 16:43f6de7bc38b 210 }
mazgch 16:43f6de7bc38b 211
mazgch 16:43f6de7bc38b 212 TRACE("Testing UDP sockets with ECHO server\r\n");
mazgch 16:43f6de7bc38b 213 socket = mdm.socketSocket(MDMParser::IPPROTO_UDP, port);
mazgch 16:43f6de7bc38b 214 if (socket >= 0)
mazgch 16:43f6de7bc38b 215 {
mazgch 16:43f6de7bc38b 216 mdm.socketSetBlocking(socket, 10000);
mazgch 16:43f6de7bc38b 217 memcpy(data, "\r\nUDP", 5);
mazgch 16:43f6de7bc38b 218 ret = mdm.socketSendTo(socket, ip, port, data, sizeof(data)-1);
mazgch 16:43f6de7bc38b 219 if (ret == sizeof(data)-1) {
mazgch 16:43f6de7bc38b 220 TRACE("Socket SendTo %s:%d " IPSTR " %d \"%s\"\r\n", host, port, IPNUM(ip), ret, data);
mazgch 16:43f6de7bc38b 221 }
mazgch 16:43f6de7bc38b 222 ret = mdm.socketRecvFrom(socket, &ip, &port, buf, sizeof(buf)-1);
mazgch 16:43f6de7bc38b 223 if (ret >= 0) {
mazgch 16:43f6de7bc38b 224 TRACE("Socket RecvFrom " IPSTR ":%d %d \"%.*s\" \r\n", IPNUM(ip),port, ret, ret,buf);
mazgch 16:43f6de7bc38b 225 }
mazgch 16:43f6de7bc38b 226 mdm.socketFree(socket);
mazgch 16:43f6de7bc38b 227 }
mazgch 16:43f6de7bc38b 228
mazgch 4:90ab1ec64b0e 229 // disconnect
mazgch 10:d2da2028a233 230 TRACE("Network Disconnect\r\n");
mazgch 4:90ab1ec64b0e 231 mdm.disconnect();
mazgch 2:b77151f111a9 232 }
mazgch 2:b77151f111a9 233
mazgch 5:5366d39d3719 234 const char* ussd = "*#134#"; // You may get answer "UNKNOWN APPLICATION"
mazgch 10:d2da2028a233 235 TRACE("Send Ussd Command %s\r\n", ussd);
mazgch 5:5366d39d3719 236 ret = mdm.ussdCommand(ussd, buf);
mazgch 4:90ab1ec64b0e 237 if (ret > 0)
mazgch 10:d2da2028a233 238 TRACE("Got Ussd Answer: \"%*s\"\r\n", ret, buf);
mazgch 10:d2da2028a233 239 }
mazgch 10:d2da2028a233 240 TRACE("Checking SMS and GPS\r\n");
mazgch 10:d2da2028a233 241 char link[128] = "";
mazgch 10:d2da2028a233 242 unsigned int i = 0xFFFFFFFF;
mazgch 10:d2da2028a233 243 const int wait = 100;
mazgch 10:d2da2028a233 244 bool abort = false;
mazgch 11:b8505cbbd55c 245 //DigitalOut led(LED1);
mazgch 10:d2da2028a233 246 while (!abort) {
mazgch 11:b8505cbbd55c 247 // led = !led;
mazgch 10:d2da2028a233 248 while ((ret = gps.getMessage(buf, sizeof(buf))) > 0)
mazgch 10:d2da2028a233 249 {
mazgch 10:d2da2028a233 250 int len = LENGTH(ret);
mazgch 10:d2da2028a233 251 //TRACE("NMEA: %.*s\r\n", len-2, msg);
mazgch 14:ab7c8627f950 252 if ((PROTOCOL(ret) == GPSParser::NMEA) && (len > 6) && !strncmp("$GPGLL", buf, 6))
mazgch 4:90ab1ec64b0e 253 {
mazgch 10:d2da2028a233 254 double la = 0, lo = 0;
mazgch 10:d2da2028a233 255 char ch;
mazgch 10:d2da2028a233 256 if (gps.getNmeaAngle(1,buf,len,la) &&
mazgch 10:d2da2028a233 257 gps.getNmeaAngle(3,buf,len,lo) &&
mazgch 10:d2da2028a233 258 gps.getNmeaItem(6,buf,len,ch) && ch == 'A')
mazgch 4:90ab1ec64b0e 259 {
mazgch 10:d2da2028a233 260 TRACE("GPS Location: %.5f %.5f\r\n", la, lo);
mazgch 10:d2da2028a233 261 sprintf(link, "I am here!\n"
mazgch 10:d2da2028a233 262 "https://maps.google.com/?q=%.5f,%.5f", la, lo);
mazgch 4:90ab1ec64b0e 263 }
mazgch 4:90ab1ec64b0e 264 }
mazgch 10:d2da2028a233 265 }
mazgch 10:d2da2028a233 266 if (mdmOk && (i++ == 10000/wait)) {
mazgch 10:d2da2028a233 267 i = 0;
mazgch 10:d2da2028a233 268 // check the network status
mazgch 15:ea10b6cf8c85 269 if (mdm.checkNetStatus(&netStatus)) {
mazgch 15:ea10b6cf8c85 270 if (DOTRACE) mdm.dumpNetStatus(&netStatus);
mazgch 15:ea10b6cf8c85 271 }
mazgch 10:d2da2028a233 272
mazgch 10:d2da2028a233 273 // checking unread sms
mazgch 10:d2da2028a233 274 int ix[8];
mazgch 10:d2da2028a233 275 int n = mdm.smsList("REC UNREAD", ix, 8);
mazgch 10:d2da2028a233 276 if (8 < n) n = 8;
mazgch 10:d2da2028a233 277 while (0 < n--)
mazgch 10:d2da2028a233 278 {
mazgch 10:d2da2028a233 279 char num[32];
mazgch 10:d2da2028a233 280 TRACE("Unread SMS at index %d\r\n", ix[n]);
mazgch 10:d2da2028a233 281 if (mdm.smsRead(ix[n], num, buf, sizeof(buf))) {
mazgch 10:d2da2028a233 282 TRACE("Got SMS from \"%s\" with text \"%s\"\r\n", num, buf);
mazgch 10:d2da2028a233 283 TRACE("Delete SMS at index %d\r\n", ix[n]);
mazgch 10:d2da2028a233 284 mdm.smsDelete(ix[n]);
mazgch 10:d2da2028a233 285 // provide a reply
mazgch 10:d2da2028a233 286 const char* reply = "Hello my friend";
mazgch 10:d2da2028a233 287 if (strstr(buf, /*w*/"here are you"))
mazgch 10:d2da2028a233 288 reply = *link ? link : "I don't know"; // reply wil location link
mazgch 10:d2da2028a233 289 TRACE("Send SMS reply \"%s\" to \"%s\"\r\n", reply, num);
mazgch 10:d2da2028a233 290 mdm.smsSend(num, reply);
mazgch 4:90ab1ec64b0e 291 }
mazgch 4:90ab1ec64b0e 292 }
mazgch 9:26f694bc31b4 293 }
mazgch 10:d2da2028a233 294 wait_ms(wait);
lawliet 0:4e3cb26f6019 295 }
mazgch 10:d2da2028a233 296 mdm.powerOff();
mazgch 10:d2da2028a233 297 gps.powerOff();
mazgch 10:d2da2028a233 298 TRACE("Shutdown\r\n");
mazgch 10:d2da2028a233 299 #ifdef C027_USEONBOARD
mazgch 10:d2da2028a233 300 // now it is safe to switch LDOs off
mazgch 2:b77151f111a9 301 c027.mdmPower(false);
mazgch 4:90ab1ec64b0e 302 c027.gpsPower(false);
mazgch 10:d2da2028a233 303 #endif
lawliet 0:4e3cb26f6019 304 return 0;
lawliet 0:4e3cb26f6019 305 }
mazgch 2:b77151f111a9 306