Pubnub demo for AT&T IoT Starter Kit. Functionally similar to the Flow demo.

Dependencies:   FXOS8700CQ MODSERIAL mbed

http://pubnub.github.io/slides/workshop/pictures/broadcast.png

Pubnub demo for AT&T IoT Starter Kit

This demo is functionally similar to the Flow demo, so you can find general information here: https://developer.mbed.org/users/JMF/code/Avnet_ATT_Cellular_IOT/.

The only difference is that we use Pubnub to publish the measurements and subscribe to receiving the instructions to set the LED.

Settings

Pubnub related settings are:

Pubnub settings in `config_me.h`

PUBNUB_SUBSCRIBE_KEY
PUBNUB_PUBLISH_KEY
PUBNUB_CHANNEL

All are documented in their respective comments.

Pubnub context class

Similar to Pubnub SDKs, we provide a Pubnub context class. It is defined in pubnub.h header file and implemented in pubnub.cpp.

It provides only the fundamental "publish" and "subscribe" methods. They are documented in the header file.

This class is reusable in other code (it is not specific to this demo), it has a very narrow interface to the AT&T IoT cellular modem code. For example of use, you can look at the main() (in main.c).

Sample of published data

Published message w/measurement data

{"serial":"vstarterkit001","temp":89.61,"humidity":35,"accelX":0.97,"accelY":0.013,"accelZ":-0.038}

Don't worry, nobody got burnt, the temperature is in degrees Fahrenheit. :)

Publish a message (from, say, the Pubnub console http://pubnub.com/console) of the form {"LED":<name-of-the-color>} on the channel that this demo listens to (default is hello_world) to turn the LED to that color on the Starter Kit:

Turn LED to red

{"LED":"Red"}

Turn LED to green

{"LED":"Green"}

Turn LED to blue

{"LED":"Blue"}
Committer:
JMF
Date:
Sun Jul 10 00:52:49 2016 +0000
Revision:
2:0e2ef866af95
Child:
10:df54436ecd38
Adding in WNC code from Fred

Who changed what in which revision?

UserRevisionLine numberNew contents of line
JMF 2:0e2ef866af95 1 #include "mbed.h"
JMF 2:0e2ef866af95 2 #include <cctype>
JMF 2:0e2ef866af95 3 #include <string>
JMF 2:0e2ef866af95 4 #include "config_me.h"
JMF 2:0e2ef866af95 5 #include "SerialBuffered.h"
JMF 2:0e2ef866af95 6 #include "wnc_control.h"
JMF 2:0e2ef866af95 7
JMF 2:0e2ef866af95 8 extern Serial pc;
JMF 2:0e2ef866af95 9 extern Serial mdm;
JMF 2:0e2ef866af95 10 extern string MyServerIpAddress;
JMF 2:0e2ef866af95 11 extern string MySocketData;
JMF 2:0e2ef866af95 12
JMF 2:0e2ef866af95 13 int reinitialize_mdm(void);
JMF 2:0e2ef866af95 14
JMF 2:0e2ef866af95 15 enum WNC_ERR_e {
JMF 2:0e2ef866af95 16 WNC_OK =0,
JMF 2:0e2ef866af95 17 WNC_CMD_ERR = -1,
JMF 2:0e2ef866af95 18 WNC_NO_RESPONSE = -2
JMF 2:0e2ef866af95 19 };
JMF 2:0e2ef866af95 20
JMF 2:0e2ef866af95 21 // Contains result of last call to send_wnc_cmd(..)
JMF 2:0e2ef866af95 22 WNC_ERR_e WNC_MDM_ERR = WNC_OK;
JMF 2:0e2ef866af95 23
JMF 2:0e2ef866af95 24 // Contains the RAW WNC UART responses
JMF 2:0e2ef866af95 25 static string wncStr;
JMF 2:0e2ef866af95 26
JMF 2:0e2ef866af95 27 void software_init_mdm(void)
JMF 2:0e2ef866af95 28 {
JMF 2:0e2ef866af95 29 do
JMF 2:0e2ef866af95 30 {
JMF 2:0e2ef866af95 31 WNC_MDM_ERR = WNC_OK;
JMF 2:0e2ef866af95 32 at_init_wnc();
JMF 2:0e2ef866af95 33 if (WNC_MDM_ERR != WNC_OK)
JMF 2:0e2ef866af95 34 reinitialize_mdm();
JMF 2:0e2ef866af95 35 } while (WNC_MDM_ERR != WNC_OK);
JMF 2:0e2ef866af95 36 }
JMF 2:0e2ef866af95 37
JMF 2:0e2ef866af95 38 void resolve_mdm(void)
JMF 2:0e2ef866af95 39 {
JMF 2:0e2ef866af95 40 do
JMF 2:0e2ef866af95 41 {
JMF 2:0e2ef866af95 42 WNC_MDM_ERR = WNC_OK;
JMF 2:0e2ef866af95 43 at_dnsresolve_wnc(MY_SERVER_URL, &MyServerIpAddress);
JMF 2:0e2ef866af95 44 if (WNC_MDM_ERR == WNC_NO_RESPONSE)
JMF 2:0e2ef866af95 45 {
JMF 2:0e2ef866af95 46 reinitialize_mdm();
JMF 2:0e2ef866af95 47 software_init_mdm();
JMF 2:0e2ef866af95 48 }
JMF 2:0e2ef866af95 49 else if (WNC_MDM_ERR == WNC_CMD_ERR)
JMF 2:0e2ef866af95 50 {
JMF 2:0e2ef866af95 51 pc.puts("Bad URL!!!!!!\r\n");
JMF 2:0e2ef866af95 52 MyServerIpAddress = "192.168.0.1";
JMF 2:0e2ef866af95 53 WNC_MDM_ERR = WNC_OK;
JMF 2:0e2ef866af95 54 }
JMF 2:0e2ef866af95 55 } while (WNC_MDM_ERR != WNC_OK);
JMF 2:0e2ef866af95 56
JMF 2:0e2ef866af95 57 pc.printf("My Server IP: %s\r\n", MyServerIpAddress.data());
JMF 2:0e2ef866af95 58 }
JMF 2:0e2ef866af95 59
JMF 2:0e2ef866af95 60 void sockopen_mdm(void)
JMF 2:0e2ef866af95 61 {
JMF 2:0e2ef866af95 62 do
JMF 2:0e2ef866af95 63 {
JMF 2:0e2ef866af95 64 WNC_MDM_ERR = WNC_OK;
JMF 2:0e2ef866af95 65 at_sockopen_wnc(MyServerIpAddress, MY_PORT_STR);
JMF 2:0e2ef866af95 66 if (WNC_MDM_ERR == WNC_NO_RESPONSE)
JMF 2:0e2ef866af95 67 {
JMF 2:0e2ef866af95 68 reinitialize_mdm();
JMF 2:0e2ef866af95 69 software_init_mdm();
JMF 2:0e2ef866af95 70 }
JMF 2:0e2ef866af95 71 else if (WNC_MDM_ERR == WNC_CMD_ERR)
JMF 2:0e2ef866af95 72 pc.puts("Socket open fail!!!!\r\n");
JMF 2:0e2ef866af95 73 } while (WNC_MDM_ERR != WNC_OK);
JMF 2:0e2ef866af95 74 }
JMF 2:0e2ef866af95 75
JMF 2:0e2ef866af95 76 void sockwrite_mdm(const char * s)
JMF 2:0e2ef866af95 77 {
JMF 2:0e2ef866af95 78 do
JMF 2:0e2ef866af95 79 {
JMF 2:0e2ef866af95 80 WNC_MDM_ERR = WNC_OK;
JMF 2:0e2ef866af95 81 at_sockwrite_wnc(s);
JMF 2:0e2ef866af95 82 if (WNC_MDM_ERR == WNC_NO_RESPONSE)
JMF 2:0e2ef866af95 83 {
JMF 2:0e2ef866af95 84 reinitialize_mdm();
JMF 2:0e2ef866af95 85 software_init_mdm();
JMF 2:0e2ef866af95 86 }
JMF 2:0e2ef866af95 87 else if (WNC_MDM_ERR == WNC_CMD_ERR)
JMF 2:0e2ef866af95 88 {
JMF 2:0e2ef866af95 89 pc.puts("Socket Write fail!!!\r\n");
JMF 2:0e2ef866af95 90 // Have seen when write fails modem gets stuck in bad state, try to recover
JMF 2:0e2ef866af95 91 reinitialize_mdm();
JMF 2:0e2ef866af95 92 software_init_mdm();
JMF 2:0e2ef866af95 93 }
JMF 2:0e2ef866af95 94 } while (WNC_MDM_ERR != WNC_OK);
JMF 2:0e2ef866af95 95 }
JMF 2:0e2ef866af95 96
JMF 2:0e2ef866af95 97 void sockread_mdm(string * sockData, int len, int retries)
JMF 2:0e2ef866af95 98 {
JMF 2:0e2ef866af95 99 do
JMF 2:0e2ef866af95 100 {
JMF 2:0e2ef866af95 101 WNC_MDM_ERR = WNC_OK;
JMF 2:0e2ef866af95 102 at_sockread_wnc(sockData, len, retries);
JMF 2:0e2ef866af95 103 if (WNC_MDM_ERR == WNC_NO_RESPONSE)
JMF 2:0e2ef866af95 104 {
JMF 2:0e2ef866af95 105 reinitialize_mdm();
JMF 2:0e2ef866af95 106 software_init_mdm();
JMF 2:0e2ef866af95 107 }
JMF 2:0e2ef866af95 108 else if (WNC_MDM_ERR == WNC_CMD_ERR)
JMF 2:0e2ef866af95 109 puts("Sock read fail!!!!\r\n");
JMF 2:0e2ef866af95 110 } while (WNC_MDM_ERR != WNC_OK);
JMF 2:0e2ef866af95 111 }
JMF 2:0e2ef866af95 112
JMF 2:0e2ef866af95 113 void sockclose_mdm(void)
JMF 2:0e2ef866af95 114 {
JMF 2:0e2ef866af95 115 do
JMF 2:0e2ef866af95 116 {
JMF 2:0e2ef866af95 117 WNC_MDM_ERR = WNC_OK;
JMF 2:0e2ef866af95 118 at_sockclose_wnc();
JMF 2:0e2ef866af95 119 if (WNC_MDM_ERR == WNC_NO_RESPONSE)
JMF 2:0e2ef866af95 120 {
JMF 2:0e2ef866af95 121 reinitialize_mdm();
JMF 2:0e2ef866af95 122 software_init_mdm();
JMF 2:0e2ef866af95 123 }
JMF 2:0e2ef866af95 124 else if (WNC_MDM_ERR == WNC_CMD_ERR)
JMF 2:0e2ef866af95 125 puts("Sock close fail!!!\r\n");
JMF 2:0e2ef866af95 126 } while (WNC_MDM_ERR != WNC_OK);
JMF 2:0e2ef866af95 127 }
JMF 2:0e2ef866af95 128
JMF 2:0e2ef866af95 129 /**
JMF 2:0e2ef866af95 130 * C++ version 0.4 char* style "itoa":
JMF 2:0e2ef866af95 131 * Written by Lukás Chmela
JMF 2:0e2ef866af95 132 * Released under GPLv3.
JMF 2:0e2ef866af95 133 */
JMF 2:0e2ef866af95 134
JMF 2:0e2ef866af95 135 char* itoa(int value, char* result, int base)
JMF 2:0e2ef866af95 136 {
JMF 2:0e2ef866af95 137 // check that the base if valid
JMF 2:0e2ef866af95 138 if ( base < 2 || base > 36 ) {
JMF 2:0e2ef866af95 139 *result = '\0';
JMF 2:0e2ef866af95 140 return result;
JMF 2:0e2ef866af95 141 }
JMF 2:0e2ef866af95 142
JMF 2:0e2ef866af95 143 char* ptr = result, *ptr1 = result, tmp_char;
JMF 2:0e2ef866af95 144 int tmp_value;
JMF 2:0e2ef866af95 145
JMF 2:0e2ef866af95 146 do {
JMF 2:0e2ef866af95 147 tmp_value = value;
JMF 2:0e2ef866af95 148 value /= base;
JMF 2:0e2ef866af95 149 *ptr++ = "zyxwvutsrqponmlkjihgfedcba9876543210123456789abcdefghijklmnopqrstuvwxyz"[35 + (tmp_value - value * base)];
JMF 2:0e2ef866af95 150 } while ( value );
JMF 2:0e2ef866af95 151
JMF 2:0e2ef866af95 152 // Apply negative sign
JMF 2:0e2ef866af95 153 if ( tmp_value < 0 )
JMF 2:0e2ef866af95 154 *ptr++ = '-';
JMF 2:0e2ef866af95 155 *ptr-- = '\0';
JMF 2:0e2ef866af95 156
JMF 2:0e2ef866af95 157 while ( ptr1 < ptr ) {
JMF 2:0e2ef866af95 158 tmp_char = *ptr;
JMF 2:0e2ef866af95 159 *ptr-- = *ptr1;
JMF 2:0e2ef866af95 160 *ptr1++ = tmp_char;
JMF 2:0e2ef866af95 161 }
JMF 2:0e2ef866af95 162
JMF 2:0e2ef866af95 163 return result;
JMF 2:0e2ef866af95 164 }
JMF 2:0e2ef866af95 165
JMF 2:0e2ef866af95 166 extern int mdm_sendAtCmdRsp(const char *cmd, const char **rsp_list, int timeout_ms, string * rsp, int * len);
JMF 2:0e2ef866af95 167
JMF 2:0e2ef866af95 168 // Sets a global with failure or success, assumes 1 thread all the time
JMF 2:0e2ef866af95 169 int send_wnc_cmd(const char * s, string ** r, int ms_timeout)
JMF 2:0e2ef866af95 170 {
JMF 2:0e2ef866af95 171 static const char * rsp_lst[] = { "OK", "ERROR", NULL };
JMF 2:0e2ef866af95 172 int len;
JMF 2:0e2ef866af95 173
JMF 2:0e2ef866af95 174 pc.printf("Send: %s\r\n",s);
JMF 2:0e2ef866af95 175 int res = mdm_sendAtCmdRsp(s, rsp_lst, ms_timeout, &wncStr, &len);
JMF 2:0e2ef866af95 176 *r = &wncStr; // Return a pointer to the static string
JMF 2:0e2ef866af95 177
JMF 2:0e2ef866af95 178 if (res >= 0)
JMF 2:0e2ef866af95 179 {
JMF 2:0e2ef866af95 180 pc.puts("[");
JMF 2:0e2ef866af95 181 pc.puts(wncStr.data());
JMF 2:0e2ef866af95 182 pc.puts("]\n\r");
JMF 2:0e2ef866af95 183 if (res > 0)
JMF 2:0e2ef866af95 184 {
JMF 2:0e2ef866af95 185 if (WNC_MDM_ERR != WNC_NO_RESPONSE)
JMF 2:0e2ef866af95 186 WNC_MDM_ERR = WNC_CMD_ERR;
JMF 2:0e2ef866af95 187 return -1;
JMF 2:0e2ef866af95 188 }
JMF 2:0e2ef866af95 189 else
JMF 2:0e2ef866af95 190 return 0;
JMF 2:0e2ef866af95 191 }
JMF 2:0e2ef866af95 192 else
JMF 2:0e2ef866af95 193 {
JMF 2:0e2ef866af95 194 WNC_MDM_ERR = WNC_NO_RESPONSE;
JMF 2:0e2ef866af95 195 pc.puts("No response from WNC!\n\r");
JMF 2:0e2ef866af95 196 return -2;
JMF 2:0e2ef866af95 197 }
JMF 2:0e2ef866af95 198 }
JMF 2:0e2ef866af95 199
JMF 2:0e2ef866af95 200 void at_init_wnc(void)
JMF 2:0e2ef866af95 201 {
JMF 2:0e2ef866af95 202 string * pRespStr;
JMF 2:0e2ef866af95 203 send_wnc_cmd("AT", &pRespStr, WNC_TIMEOUT_MS); // Heartbeat?
JMF 2:0e2ef866af95 204 send_wnc_cmd("ATE1", &pRespStr, WNC_TIMEOUT_MS); // Echo ON
JMF 2:0e2ef866af95 205 string cmd_str("AT%PDNSET=1,");
JMF 2:0e2ef866af95 206 cmd_str += MY_APN_STR;
JMF 2:0e2ef866af95 207 cmd_str += ",IP";
JMF 2:0e2ef866af95 208 send_wnc_cmd(cmd_str.data(), &pRespStr, 2*WNC_TIMEOUT_MS); // Set APN, cmd seems to take a little longer sometimes
JMF 2:0e2ef866af95 209 send_wnc_cmd("AT@INTERNET=1", &pRespStr, WNC_TIMEOUT_MS); // Internet services enabled
JMF 2:0e2ef866af95 210 send_wnc_cmd("AT@SOCKDIAL=1", &pRespStr, WNC_TIMEOUT_MS);
JMF 2:0e2ef866af95 211 }
JMF 2:0e2ef866af95 212
JMF 2:0e2ef866af95 213 void at_sockopen_wnc(const string & ipStr, const char * port )
JMF 2:0e2ef866af95 214 {
JMF 2:0e2ef866af95 215 string * pRespStr;
JMF 2:0e2ef866af95 216 send_wnc_cmd("AT@SOCKCREAT=1", &pRespStr, WNC_TIMEOUT_MS);
JMF 2:0e2ef866af95 217 string cmd_str("AT@SOCKCONN=1,\"");
JMF 2:0e2ef866af95 218 cmd_str += ipStr;
JMF 2:0e2ef866af95 219 cmd_str += "\",";
JMF 2:0e2ef866af95 220 cmd_str += port;
JMF 2:0e2ef866af95 221 send_wnc_cmd(cmd_str.data(), &pRespStr, WNC_TIMEOUT_MS);
JMF 2:0e2ef866af95 222 }
JMF 2:0e2ef866af95 223
JMF 2:0e2ef866af95 224 void at_sockclose_wnc(void)
JMF 2:0e2ef866af95 225 {
JMF 2:0e2ef866af95 226 string * pRespStr;
JMF 2:0e2ef866af95 227 send_wnc_cmd("AT@SOCKCLOSE=1", &pRespStr, WNC_TIMEOUT_MS);
JMF 2:0e2ef866af95 228 }
JMF 2:0e2ef866af95 229
JMF 2:0e2ef866af95 230 int at_dnsresolve_wnc(const char * s, string * ipStr)
JMF 2:0e2ef866af95 231 {
JMF 2:0e2ef866af95 232 string * pRespStr;
JMF 2:0e2ef866af95 233 string str(s);
JMF 2:0e2ef866af95 234 str = "AT@DNSRESVDON=\"" + str;
JMF 2:0e2ef866af95 235 str += "\"\r\n";
JMF 2:0e2ef866af95 236 if (send_wnc_cmd(str.data(), &pRespStr, WNC_TIMEOUT_MS) == 0)
JMF 2:0e2ef866af95 237 {
JMF 2:0e2ef866af95 238 size_t pos_start = pRespStr->find(":\"") + 2;
JMF 2:0e2ef866af95 239 if (pos_start != string::npos)
JMF 2:0e2ef866af95 240 {
JMF 2:0e2ef866af95 241 size_t pos_end = pRespStr->rfind("\"") - 1;
JMF 2:0e2ef866af95 242 if (pos_end != string::npos)
JMF 2:0e2ef866af95 243 {
JMF 2:0e2ef866af95 244 if (pos_end > pos_start)
JMF 2:0e2ef866af95 245 {
JMF 2:0e2ef866af95 246 // Make a copy for use later (the source string is re-used)
JMF 2:0e2ef866af95 247 *ipStr = pRespStr->substr(pos_start, pos_end - pos_start + 1);
JMF 2:0e2ef866af95 248 return 1;
JMF 2:0e2ef866af95 249 }
JMF 2:0e2ef866af95 250 else
JMF 2:0e2ef866af95 251 pc.puts("URL Resolve fail, substr Err\r\n");
JMF 2:0e2ef866af95 252 }
JMF 2:0e2ef866af95 253 else
JMF 2:0e2ef866af95 254 pc.puts("URL Resolve fail, no 2nd quote\r\n");
JMF 2:0e2ef866af95 255 }
JMF 2:0e2ef866af95 256 else
JMF 2:0e2ef866af95 257 pc.puts("URL Resolve fail, no quotes\r\n");
JMF 2:0e2ef866af95 258 }
JMF 2:0e2ef866af95 259 else
JMF 2:0e2ef866af95 260 pc.puts("URL Resolve fail, WNC cmd fail\r\n");
JMF 2:0e2ef866af95 261
JMF 2:0e2ef866af95 262 return -1;
JMF 2:0e2ef866af95 263 }
JMF 2:0e2ef866af95 264
JMF 2:0e2ef866af95 265 void at_sockwrite_wnc(const char * s)
JMF 2:0e2ef866af95 266 {
JMF 2:0e2ef866af95 267 string * pRespStr;
JMF 2:0e2ef866af95 268 char num2str[6];
JMF 2:0e2ef866af95 269 size_t sLen = strlen(s);
JMF 2:0e2ef866af95 270 if (sLen <= 99999)
JMF 2:0e2ef866af95 271 {
JMF 2:0e2ef866af95 272 string cmd_str("AT@SOCKWRITE=1,");
JMF 2:0e2ef866af95 273 itoa(sLen, num2str, 10);
JMF 2:0e2ef866af95 274 cmd_str += num2str;
JMF 2:0e2ef866af95 275 cmd_str += ",\"";
JMF 2:0e2ef866af95 276 while(*s != '\0')
JMF 2:0e2ef866af95 277 {
JMF 2:0e2ef866af95 278 itoa((int)*s++, num2str, 16);
JMF 2:0e2ef866af95 279 // Always 2-digit ascii hex:
JMF 2:0e2ef866af95 280 if (strlen(num2str) == 1)
JMF 2:0e2ef866af95 281 {
JMF 2:0e2ef866af95 282 num2str[2] = '\0';
JMF 2:0e2ef866af95 283 num2str[1] = num2str[0];
JMF 2:0e2ef866af95 284 num2str[0] = '0';
JMF 2:0e2ef866af95 285 }
JMF 2:0e2ef866af95 286 cmd_str += num2str;
JMF 2:0e2ef866af95 287 }
JMF 2:0e2ef866af95 288 cmd_str += "\"";
JMF 2:0e2ef866af95 289 send_wnc_cmd(cmd_str.data(), &pRespStr, WNC_TIMEOUT_MS);
JMF 2:0e2ef866af95 290 }
JMF 2:0e2ef866af95 291 else
JMF 2:0e2ef866af95 292 pc.puts("sockwrite Err, string to long\r\n");
JMF 2:0e2ef866af95 293 }
JMF 2:0e2ef866af95 294
JMF 2:0e2ef866af95 295 unsigned at_sockread_wnc(string * pS, unsigned n, unsigned retries = 0)
JMF 2:0e2ef866af95 296 {
JMF 2:0e2ef866af95 297 unsigned i;
JMF 2:0e2ef866af95 298 string * pRespStr;
JMF 2:0e2ef866af95 299 string cmd_str("AT@SOCKREAD=1,");
JMF 2:0e2ef866af95 300 if (n <= 1500)
JMF 2:0e2ef866af95 301 {
JMF 2:0e2ef866af95 302 char num2str[6];
JMF 2:0e2ef866af95 303 itoa(n, num2str, 10);
JMF 2:0e2ef866af95 304 cmd_str += num2str;
JMF 2:0e2ef866af95 305 retries += 1;
JMF 2:0e2ef866af95 306 while (retries--)
JMF 2:0e2ef866af95 307 {
JMF 2:0e2ef866af95 308 send_wnc_cmd(cmd_str.data(), &pRespStr, WNC_TIMEOUT_MS);
JMF 2:0e2ef866af95 309 size_t pos_start = pRespStr->find("\"") + 1;
JMF 2:0e2ef866af95 310 size_t pos_end = pRespStr->rfind("\"") - 1;
JMF 2:0e2ef866af95 311 i = pos_end - pos_start + 1;
JMF 2:0e2ef866af95 312 if (i > 0)
JMF 2:0e2ef866af95 313 {
JMF 2:0e2ef866af95 314 retries = 0; // If any data found stop retrying
JMF 2:0e2ef866af95 315 string byte;
JMF 2:0e2ef866af95 316 pS->erase();
JMF 2:0e2ef866af95 317 while (pos_start < pos_end)
JMF 2:0e2ef866af95 318 {
JMF 2:0e2ef866af95 319 byte = pRespStr->substr(pos_start, 2);
JMF 2:0e2ef866af95 320 *pS += (char)strtol(byte.data(), NULL, 16);
JMF 2:0e2ef866af95 321 pos_start += 2;
JMF 2:0e2ef866af95 322 }
JMF 2:0e2ef866af95 323 return i;
JMF 2:0e2ef866af95 324 }
JMF 2:0e2ef866af95 325 }
JMF 2:0e2ef866af95 326 }
JMF 2:0e2ef866af95 327 else
JMF 2:0e2ef866af95 328 pc.puts("sockread Err, to many to read\r\n");
JMF 2:0e2ef866af95 329
JMF 2:0e2ef866af95 330 return 0;
JMF 2:0e2ef866af95 331 }