iotivity 0.9.0
[platform/upstream/iotivity.git] / service / soft-sensor-manager / SampleApp / arduino / Trackee_Thing / src / bleLib.cpp
1 /*
2  * blsLib.cpp
3  *
4  *  Created on: 2014. 11. 5.
5  *      Author: eunseok
6  */
7
8 #include "bleLib.h"
9 #include <stdarg.h>
10 #include "trackee.h"
11
12 //#define __INTERNAL_DEBUG__            1
13
14 PROGMEM const char TAG[] = "TrackeeSensor";
15 #define LIMIT_COUNT                     100
16 #define DUMMY_SIZE                      30
17 #define DEBUG_SIZE                      DUMMY_SIZE
18 #if (ARDUINO != 0)
19 #define SERIAL_SIZE                     100
20 #endif
21
22 #define BLE             Serial2
23
24 bool isConnected = false;
25 int SerialCnt=0;
26 int BLECnt=0;
27 char SelfMaxaddr[19] = {0,};
28
29 char debugD[DEBUG_SIZE]={0,};
30
31 #if (ARDUINO != 0)
32 char SerialData[SERIAL_SIZE]={0,};
33 char BLEData[SERIAL_SIZE]={0,};
34 #endif
35
36 // baudRate이 115200이면, 주의해야한다.
37 // Arduino Chip은 16bit Process 이므로 int형의 사이즈가 4byte형 signed int이다.
38 void Cble::init(long baudRate, int ble_mode, char* SelfMaxAddr)
39 {
40         debug_printf("BLE shiled is initialed.-\r\n");
41
42         if(SelfMaxAddr == NULL && ble_mode != BLE_NOCHANGE )
43         {
44                 debug_printf("Error : Insert Maxaddress of Arduino BLE shiled.\r\n");
45                 exit(-1);
46         }
47         sprintf(SelfMaxaddr, "%s",SelfMaxAddr);
48
49         BLE.begin(baudRate);
50         BLE.setTimeout(1);
51         delay(1000);
52
53         memset(debugD,0,DEBUG_SIZE);
54
55         if( ble_mode != BLE_NOCHANGE )
56         {
57                 while( IsSelfArduino() == false )
58                         this->pollingDisconnect();
59         }
60
61         if( ble_mode == BLE_MASTER )
62         {
63                 pollingRequest("AT+ROLE1", debugD, 8);
64                 memset(debugD, 0, DEBUG_SIZE);
65                 delay(150);
66                 pollingRequest("AT+MODE0", debugD, 8);
67                 memset(debugD, 0, DEBUG_SIZE);
68                 delay(150);
69                 pollingRequest("AT+NOTI0", debugD, 8);
70                 memset(debugD, 0, DEBUG_SIZE);
71         }
72         else if ( ble_mode == BLE_SLAVER )
73         {
74                 pollingRequest("AT+ROLE0", debugD, 8);
75                 memset(debugD, 0, DEBUG_SIZE);
76                 delay(150);
77                 pollingRequest("AT+MODE2", debugD, 8);
78                 memset(debugD, 0, DEBUG_SIZE);
79                 delay(150);
80                 pollingRequest("AT+NOTI0", debugD, 8);
81                 memset(debugD, 0, DEBUG_SIZE);
82         }
83
84         if( ble_mode != BLE_NOCHANGE )
85         {
86                 while( IsSelfArduino() == false )
87                         this->pollingDisconnect();
88         }
89
90         delay(250);
91 }
92
93 void Cble::StatusRead( void )
94 {
95         debug_printf("StatusRead function called.\r\n");
96
97         pollingRequest("AT+ROLE?", debugD, 9);
98         memset(debugD, 0, DEBUG_SIZE);
99         delay(150);
100         pollingRequest("AT+MODE?", debugD, 8);
101         memset(debugD, 0, DEBUG_SIZE);
102         delay(150);
103         pollingRequest("AT+IMME?", debugD, 9);
104         memset(debugD, 0, DEBUG_SIZE);
105         delay(150);
106         pollingRequest("AT+TYPE?", debugD, 8);
107         memset(debugD, 0, DEBUG_SIZE);
108         delay(150);
109         pollingRequest("AT+POWE?", debugD, 8);
110         memset(debugD, 0, DEBUG_SIZE);
111         delay(150);
112         pollingRequest("AT+NOTI?", debugD, 8);
113         memset(debugD, 0, DEBUG_SIZE);
114         delay(150);
115         pollingRequest("AT+PIO1?", debugD, 8);
116         memset(debugD, 0, DEBUG_SIZE);
117         delay(150);
118 }
119
120 bool Cble::IsConnected( void )
121 {
122         return isConnected;
123 }
124
125 bool Cble::IsSelfArduino( void )
126 {
127 #ifdef __INTERNAL_DEBUG__
128         debug_printf("IsSelfArduino is called.\r\n");
129 #endif
130         int length=mustHaveRequest("AT+ADDR?", debugD, 20);
131
132         if( strstr(debugD, SelfMaxaddr) )
133         {
134                 isConnected = false;
135                 memset(debugD,0,length);
136                 return true;
137         }
138         else
139         {
140                 isConnected = true;
141                 memset(debugD,0,length);
142                 return false;
143         }
144 }
145
146 bool Cble::pollingConnect( const char* maxAddr )
147 {
148 #ifdef __INTERNAL_DEBUG__
149         debug_printf("pollingConnect is called.\r\n");
150 #endif
151
152 #define CONNECT_SIZE            20
153
154         char cmd[CONNECT_SIZE]= {0,};
155
156         // is Connected Address ?
157         pollingRequest("AT+ADDR?", debugD, 20);
158         if( strstr(debugD, maxAddr) )
159         {
160                 isConnected = true;
161                 memset(debugD,0,DEBUG_SIZE);
162                 return isConnected;
163         }
164         memset(debugD,0,DEBUG_SIZE);
165
166         // Try Connection.
167         sprintf(cmd, "AT+CON%s",maxAddr);
168         if( pollingRequest(cmd, debugD, 8) == false )
169         {
170                 debug_printf("Error : %s command is failed.\r\n",cmd );
171                 memset(debugD,0,DEBUG_SIZE);
172                 pollingDisconnect();
173                 return false;
174         }
175         else if( strstr(debugD,"OK+CONNA") )
176         {
177                 isConnected = true;
178                 memset(debugD,0,DEBUG_SIZE);
179         }
180         else
181         {
182                 memset(debugD,0,DEBUG_SIZE);
183                 pollingDisconnect();
184                 return false;
185         }
186         // Confirm Connected Address.
187         pollingRequest("AT+ADDR?", debugD, 20);
188
189         if( strstr(debugD, maxAddr) == 0 )
190         {
191                 isConnected = false;
192                 if ( strstr(debugD, "OK+CONNF") )
193                 {
194                         memset(debugD,0,DEBUG_SIZE);
195                         streamDummy(debugD, 8);
196                 }
197         }
198         memset(debugD,0,DEBUG_SIZE);
199         delay(5);
200
201         return isConnected;
202
203 #undef CONNECT_SIZE
204 }
205
206
207 #define  CMD_DISCONNECT         "(CMD_DISCON)"
208 void Cble::pollingDisconnect( void )
209 {
210 #ifdef __INTERNAL_DEBUG__
211         debug_printf("pollingDisconnect is called.\r\n");
212 #endif
213         int length=0;
214 #if (ARDUINO == 0)
215         pollingRequest("\r\n" CMD_DISCONNECT "\r\n", NULL, NULL);
216         delay(5);
217
218         length=mustHaveRequest("AT", debugD, 2);
219         if( strstr(debugD,"OK") )
220                 isConnected = false;
221
222         memset(debugD,0,length);
223 #else
224         if( BLE.available() )
225         {
226                 if( BLE.findUntil(CMD_DISCONNECT, "\r\n") == true )
227                 {
228                         debug_printf("pollingDisconnect : Detected %s command.\r\n", CMD_DISCONNECT);
229
230                         do {
231                                 debug_printf("pollingDisconnect : Send AT message.\r\n");
232                                 if( length )
233                                         memset(debugD, 0, length);
234
235                                 length=mustHaveRequest("AT", debugD, 2);
236                         }while( strstr(debugD,"OK") == NULL );
237
238                         debug_printf("pollingDisconnect() is Success.\r\n");
239                         memset(debugD, 0, length);
240                 }
241         }
242 #endif
243
244         delay(5);
245 }
246
247 int Cble::pollingGetRSSI( void )
248 {
249 #define RSSI_SIZE               11
250 #define RSSI_POS                7
251
252         long time_cnt=0;
253         char c=0;
254         char index=0;
255         char rssi_res[RSSI_SIZE] = {0,};
256
257         streamDummy(NULL, NULL);
258
259         if( isConnected == true )
260         {
261                 BLE.write("AT+RSSI?");
262                 BLE.flush();
263                 delay(5);
264
265                 while(1)
266                 {
267                         if ( BLE.available() )
268                                 c = (char)BLE.read();
269                         else
270                         {
271                                 c = 0;
272                                 time_cnt++;
273                         }
274
275                         if( c )
276                         {
277                                 rssi_res[index] = c;
278                                 index++;
279                                 if( index == RSSI_SIZE-1 )
280                                 {
281                                         rssi_res[index] = '\0';
282                                         goto RESULT;
283                                 }
284                         }
285
286         //              debug_printf("time_cnt=%d\r\n", time_cnt);
287                         if( time_cnt == 0xFFFFF )
288                         {
289                                 debug_printf("Error : Time Out GetRSSI().\r\n");
290                                 return BLE_NODATA;
291                         }
292
293                 }
294
295         RESULT :
296 #ifdef __INTERNAL_DEBUG__
297                 debug_printf("res= %s \r\n",rssi_res);
298 #endif
299                 char* Srssi = &(rssi_res[RSSI_POS]);
300         //      debug_printf("[S] rssi=%s\r\n", Srssi);
301                 int rssi = atoi(Srssi);
302         //      debug_printf("rssi=%d\r\n", rssi);
303
304                 return rssi;
305         }
306
307         return BLE_DISCON;
308
309 #undef RSSI_POS
310 #undef RSSI_SIZE
311 }
312
313 int Cble::mustHaveRequest(const char* request, char* data, int dataLen)
314 {
315         int cnt=0;
316         int length=0;
317         int required_length = dataLen;
318         char* data_index = data;
319
320         BLE.write(request);
321         BLE.flush();
322         delay(150);
323
324 READ_STREAM :
325         while( (length=BLE.readBytes(data_index, required_length)) == 0 )
326         {
327                 cnt++;
328                 delay(10);
329
330                 if ( cnt >= LIMIT_COUNT/10 )
331                 {
332 #ifdef __INTERNAL_DEBUG__
333                         debug_printf("=====> Retry Request command Send. <=========\r\n");
334 #endif
335                         cnt = 0;
336                         BLE.write(request);
337                         BLE.flush();
338
339                         required_length = dataLen;
340                         data_index = data;
341                         length = 0;
342                         delay(50);
343                 }
344         }
345
346         required_length -= length;
347         if( required_length != 0 )
348         {
349                 data_index = data_index + length;
350                 length = 0;
351                 goto READ_STREAM;
352         }
353
354 #ifdef __INTERNAL_DEBUG__
355         debug_printf("[ %s ] %s\r\n\r\n", request, data);
356 #endif
357         return dataLen;
358 }
359
360 bool Cble::pollingRequest(const char* request, char* data, int dataLen)
361 {
362         int cnt=0;
363         int length=0;
364         int required_length = dataLen;
365         char* data_index = data;
366
367         BLE.write(request);
368         BLE.flush();
369
370         if( data_index )
371         {
372                 delay(250);
373
374 READ_STREAM :
375                 while( (length=BLE.readBytes(data_index, required_length)) == 0 )
376                 {
377                         cnt++;
378                         if ( cnt >= LIMIT_COUNT )
379                         {
380                                 debug_printf("[ %s ] TimeOut : No data.\r\n\r\n", request);
381                                 return false;
382                         }
383                 }
384
385                 required_length -= length;
386                 if( required_length != 0 )
387                 {
388                         data_index = data_index + length;
389                         length = 0;
390                         goto READ_STREAM;
391                 }
392
393 #ifdef __INTERNAL_DEBUG__
394                 debug_printf("[ %s ] %s\r\n\r\n", request, data);
395 #endif
396         }
397         return true;
398 }
399
400 void Cble::streamDummy( char* data, int dataLen)
401 {
402         int cnt=0;
403         int length=0;
404         int required_length = dataLen;
405         char* data_index = data;
406
407         if( data && required_length )
408         {
409 READ_STREAM :
410                 while( (length=BLE.readBytes(data_index, required_length)) == 0 )
411                 {
412                         cnt++;
413                         if ( cnt >= LIMIT_COUNT )
414                         {
415                                 debug_printf("[ streamDummy ] TimeOut : No data.\r\n\r\n");
416                                 return ;
417                         }
418                 }
419
420                 required_length -= length;
421                 if( required_length != 0 )
422                 {
423                         data_index = data_index + length;
424                         length = 0;
425                         goto READ_STREAM;
426                 }
427
428                 debug_printf("[ streamDummy ] %s\r\n\r\n", data);
429         }
430         else
431         {
432                 if( BLE.available() )
433                 {
434                         BLE.readBytes(debugD, DEBUG_SIZE);
435 #ifdef __INTERNAL_DEBUG__
436                         debug_printf("[ streamDummy ] %s\r\n\r\n", debugD);
437 #endif
438                         memset(debugD, 0, DEBUG_SIZE);
439                 }
440         }
441
442 }
443
444 #if (ARDUINO != 0)
445
446 #define REGARD_DISCON                   5000
447 int needDiscon = 0;
448 unsigned long global_cnt = 0;
449
450 void Cble::BLE2Debug( int autoDiscon )
451 {
452         int cnt=0;
453         uint8_t length=0;
454
455         if( BLE.available() )
456         {
457                 while( (length=BLE.readBytes(BLEData, SERIAL_SIZE)) == 0 )
458                 {
459                         cnt++;
460                         if ( cnt >= LIMIT_COUNT )
461                                 return ;
462                 }
463
464                 global_cnt = 0;
465                 needDiscon = 0;
466
467                 Serial.println(BLEData);
468                 memset(BLEData, 0, length);
469         }
470         else if ( autoDiscon )
471         {
472                 global_cnt++;
473 //              debug_printf("global_cnt=%u , ", global_cnt );
474 //              debug_printf("needDiscon=%d\r\n", needDiscon);
475                 if( !needDiscon && global_cnt >= REGARD_DISCON )
476                 {
477                         needDiscon = 1;
478                         debug_printf("result : global_cnt=%u , ", global_cnt );
479                         debug_printf("needDiscon=%d\r\n", needDiscon);
480                 }
481
482                 if ( needDiscon )
483                 {
484                         debug_printf("Auto Discon : global_cnt=%u , ", global_cnt );
485                         debug_printf("needDiscon=%d\r\n", needDiscon);
486                         if( pollingRequest("AT", debugD, 2) == true )
487                         {
488                                 global_cnt = 0;
489                                 needDiscon = 0;
490                         }
491                 }
492         }
493 }
494
495 char* Cble::Debug2BLE( int BLEwrite )
496 {
497         char* result = NULL;
498
499         if( Serial.available() )
500         {
501                 char c = (char)Serial.read();
502
503                 switch(c)
504                 {
505                 case '\0':
506                         return result;
507                 case '\r':
508                 case '\n':
509                         debug_printf("\r\n");
510                         if(BLEwrite && SerialCnt)
511                         {
512                                 BLE.write(SerialData);
513                                 BLE.flush();
514                         }
515
516                         result = (char*)malloc(sizeof(char)*(SerialCnt+1));
517                         memcpy(result, SerialData, SerialCnt );
518                         result[SerialCnt] = NULL;
519
520                         memset(SerialData, 0, SerialCnt+1);
521                         SerialCnt=0;
522                         break;
523                 default :
524                         SerialData[SerialCnt] = c;
525                         SerialCnt++;
526                         Serial.print(c);
527                         break;
528                 }
529         }
530
531         return result;
532 }
533 #else
534 void Cble::BLE2Debug( int autoDiscon )
535 {
536         ;
537 }
538
539 char* Cble::Debug2BLE( int BLEwrite )
540 {
541          return NULL;
542 }
543 #endif
544
545 void Cble::FactoryReset( void )
546 {
547         debug_printf("FactoryReset is called.\r\n");
548
549         pollingRequest("AT+RENEW", debugD, 8);
550         memset(debugD, 0, DEBUG_SIZE);
551 }
552
553
554 void Cble::firstUartSetting( void )
555 {
556         debug_printf("firstUartSetting is called.\r\n");
557
558         Serial.begin(9600);
559         BLE.begin(9600);
560         BLE.setTimeout(1);
561         delay(1000);
562
563         pollingRequest("AT+BAUD4", debugD, 8);
564         memset(debugD, 0, DEBUG_SIZE);
565
566         debug_printf("Please Power off and on.\r\n");
567         BLE.end();
568 //      delay(1000);
569 //
570 //      BLE.begin(115200);
571 //      delay(1000);
572 //
573 //      pollingRequest("AT", debugD, DEBUG_SIZE);
574 //      memset(debugD, 0, DEBUG_SIZE);
575
576
577         exit(0);
578 }
579
580
581
582
583
584
585
586