socketref,再见!高德

https://github.com/adoggie

  C++博客 :: 首页 :: 联系 :: 聚合  :: 管理
  246 Posts :: 4 Stories :: 312 Comments :: 0 Trackbacks

常用链接

留言簿(54)

我参与的团队

搜索

  •  

最新评论

阅读排行榜

评论排行榜

  1 
  2 /*
  3     name:     btsc.h
  4     desc:   蓝牙串口通信数据包装    
  5     writer:    zhangbin 
  6     date:    2007-01-25
  7     history:    
  8             2007-0206    zhangbin    
  9                 1. btsc_context增加 user
 10                 2. notifier函数原型增加 btsc_context参数,便于访问上下文
 11             2008.06.16    scott
 12                 1. 增加crc校验属性 
 13                     CRC=12345
 14                     crc校验和计算: 准备发送一个数据包之前,将默认crc属性(CRC=00000)作为属性包加入,然后将整个属性包进行crc计算出校验和
 15                                      将16位的crc sum 转换成5字节的字符串替换包属性CRC的值
 16                     <MSG=DEVICE-OPEN  CRC=00000> =>计算机校验和 45322 
 17                     替换数据包属性值=> <MSG=DEVICE-OPEN CRC=45322>  
 18                     发送
 19                 2. 增加 DataChecker
 20 */
 21 
 22 #ifndef _BTSC_H
 23 #define _BTSC_H
 24 
 25 #include <stdio.h>
 26 
 27 #define OUT
 28 #define INOUT
 29 #define IN
 30 
 31 #define INIT_LIST_HEAD(x)    
 32 
 33 #define btsc_TRUE     0
 34 #define btsc_FALSE    1
 35 #define btsc_NULL     0
 36 
 37 struct list_head{
 38     struct list_head* prev,*next;
 39 };
 40 
 41 
 42 struct btsc_Property{
 43     char *         name;
 44     char *         value;        
 45 };
 46 
 47 
 48 struct btsc_Packet{
 49     /*struct list_head    list;*/
 50     struct btsc_Property**     properties; 
 51     int                size;
 52     int                capacity;
 53     struct btsc_Context    *    ctx;
 54 };
 55 
 56 struct btsc_Packet*     btsc_Packet_Alloc(struct btsc_Context* );
 57 void                    btsc_Packet_Free(struct btsc_Packet*);
 58 
 59 struct btsc_Property*    btsc_Property_Alloc(struct btsc_Context* ,char * name,char * value);
 60 void                    btsc_Property_Free(struct btsc_Property*);
 61 
 62 
 63 
 64 struct btsc_Property*     btsc_Property_Get(struct btsc_Packet* packet,char * name);     
 65 void                    btsc_Property_Append(struct btsc_Packet* packet,struct btsc_Property * );
 66 
 67 
 68 
 69 struct btsc_Context{
 70     void (*tx)(struct btsc_Context*,unsigned char * data,int len);        
 71     int (*notifier)(struct btsc_Packet* packet);/*外部释放packet,返回NULL*/        
 72     int        packet_cached_size;
 73     int        recv_cached_capacity;                        
 74     char*    recv_buff;                                    
 75     int        recv_size;        
 76     void*    user;    // 外部数据传递                            
 77     int        crc_check;    // 0 - nocrc, 1 crc check
 78 };
 79 
 80 
 81 int     btsc_init(struct btsc_Context* IN ctx);    
 82 void     btsc_cleanup(struct btsc_Context* IN ctx);
 83 int        btsc_Pack(struct btsc_Context* IN ctx,struct btsc_Packet* packet,unsigned char * INOUT buff,int* INOUT size);    
 84 void    btsc_Parse(struct btsc_Context* , char * data,int len);
 85 
 86 
 87 #define BTSC_PACKET_BEGIN(ctx) {\
 88                                 struct btsc_Context* _ctx_internel;\
 89                                 struct btsc_Packet * _pkt ;\
 90                                 _ctx_internel= (ctx);\
 91                                 _pkt = btsc_Packet_Alloc(_ctx_internel);
 92                                 
 93 /* key is not suitable for vairable*/                                
 94 #define BTSC_NEW_PROPERTY(key,value)    {\
 95                                             struct btsc_Property * _ppt =btsc_Property_Alloc(_ctx_internel,key,value);\
 96                                             btsc_Property_Append(_pkt,_ppt);\
 97                                         }
 98 #define BTSC_PACKET_END()        btsc_Pack(_ctx_internel,_pkt,btsc_NULL,0);\
 99                                 btsc_Packet_Free(_pkt);\
100                                 }
101 
102 #define BTSC_FOREACH(packet,ppt)    {\
103                                     int n;\
104                                     for(n=0;n<packet->size;n++){\
105                                         ppt = packet->properties[n];
106 #define BTSC_END_FOREACH()            }\
107                                 }
108 
109 #endif
110 
111 


  1 
  2 
  3 /*
  4     name:            btsc
  5                     serial communicating  with bluetooth and app-user
  6     desc:            pair parameter codec
  7     
  8         packet=[ key:name,]
  9         
 10     implemented:     zhangbin 
 11     date:            2007-01-26
 12 */
 13 
 14 #include <stdio.h>
 15 #include <stdlib.h>
 16 #include <string.h>
 17 #ifdef _UNIX
 18 #include <unistd.h>
 19 #endif
 20 #include "btsc.h"
 21 #include "crc.h"
 22 
 23 #define CRC_DEFAULT_STRING "CRC=00000"
 24 #define PACKET_HEAD        '<'
 25 #define PACKET_TAIL        '>'
 26 #define PROPERTY_DELIMITER    ','
 27 #define PAIR_DELIMITER        '='
 28 //#define PAIR_DELIMITER        '$'
 29 #define ESCAPE_CHAR            '\\'
 30 
 31 
 32 int calcEscapleLength(char * str);
 33 char* escape_copy(char * dest,char * src);
 34 void trim_escape_copy(char * dest,char * src,int size);
 35 int  calcPacketLength(struct btsc_Packet* pkt);
 36 int    is_escape_char(char c);
 37 void parseProperty(struct btsc_Packet * pkt,char * s,char * e);
 38 void parsePacket(struct btsc_Context* ctx,char * s,char* e);
 39 char*     __memchr(char * s,char* e,char c);
 40 
 41 char escape_ch_table[]={PACKET_HEAD,PACKET_TAIL,PROPERTY_DELIMITER,PAIR_DELIMITER,ESCAPE_CHAR,'\0'};
 42 
 43 struct btsc_Packet*     btsc_Packet_Alloc(struct btsc_Context* ctx){    
 44     struct btsc_Packet * pt = malloc(sizeof(struct btsc_Packet));        
 45     pt->size = 0;
 46     pt->capacity = ctx->packet_cached_size;
 47     pt->properties=malloc(pt->capacity*sizeof(struct btsc_Property*));    
 48     pt->ctx = ctx;
 49     return pt;    
 50 }
 51 
 52 void    btsc_Packet_Free(struct btsc_Packet* pt){    
 53     struct btsc_Property** tmp;
 54     if!pt )     return ;
 55     tmp = pt->properties;
 56     while(pt->size--){
 57         btsc_Property_Free(*tmp++);                
 58     }        
 59     if( pt->properties){
 60         free(pt->properties);  
 61     }
 62     free(pt);
 63 }
 64 
 65 
 66 struct btsc_Property*    btsc_Property_Alloc(struct btsc_Context* ctx,char * name,char * value){
 67     struct btsc_Property * ppt;
 68 /*    printf("enter btsc_Property_Alloc()\n");*/
 69     ppt = malloc( sizeof( struct btsc_Property) );
 70     if(!ppt)    printf("error: malloc failed (s1)\n");
 71     ppt->name = malloc( strlen(name)+1);
 72     if!ppt->name ) printf("error: malloc failed (s2)\n");
 73     strcpy(ppt->name,name);    
 74     ppt->value = malloc( strlen(value)+1);
 75     if!ppt->value) printf("error: malloc failed (s3),str:%s, len: %d\n",value,strlen(value)+1);
 76     strcpy( ppt->value,value);
 77     return ppt;
 78 }
 79 
 80 void        btsc_Property_Free(struct btsc_Property* ppt){
 81     if!ppt )    return;
 82     free( ppt->name);
 83     free( ppt->value);
 84     free( ppt);
 85 }
 86 
 87 /* scan pointer array */
 88 struct btsc_Property*     btsc_Property_Get(struct btsc_Packet* pkt,char * name){
 89     int size;
 90     struct btsc_Property* ppt;
 91     size = pkt->size;
 92     while(size--){
 93         ppt = pkt->properties[size];
 94         if!strcmp( name, ppt->name ) ){
 95             return ppt;/*that's ok */
 96         }
 97     }
 98     return btsc_NULL;
 99 }
100 
101 /* low effeciency, memory allocation,more costs*/
102 void    btsc_Property_Append(struct btsc_Packet* pt,struct btsc_Property * ppt){
103     struct btsc_Property** tmpppt;
104     if( pt->size==pt->capacity){         
105         pt->capacity += pt->ctx->packet_cached_size;    
106         tmpppt = pt->properties;        
107         pt->properties = malloc( pt->capacity * sizeof( struct btsc_Property**) ); 
108         memcpy( pt->properties, tmpppt, pt->size * sizeof( struct btsc_Property**));
109         free( tmpppt); 
110     }
111     pt->properties[pt->size++]=ppt;    
112 }
113 
114 int     btsc_init(struct btsc_Context* ctx){    
115     ctx->packet_cached_size = 10;    
116     if( ctx->recv_cached_capacity==0){
117         ctx->recv_cached_capacity = 1024*2;    
118     }
119     ctx->recv_buff = malloc( ctx->recv_cached_capacity );
120     ctx->recv_size = 0;
121     ctx->crc_check = 1;
122     return btsc_TRUE;
123 }
124 
125 void     btsc_cleanup(struct btsc_Context* ctx){
126     free(ctx->recv_buff);    
127 }
128 
129 /*
130 **    name:    calcEscapleLength
131 **    desc:    计算含转义字符串长度
132 */
133 int     calcEscapleLength(char * str){
134     int len;
135     char * pesc;
136     len = 0;    
137     while*str ){
138         pesc = escape_ch_table;
139         while*pesc ){
140             if*pesc==*str){
141                 len++;
142                 break;
143             }
144             pesc++;
145         }        
146         str++
147     }    
148     return len;
149 }
150 
151 
152 char* escape_copy(char * dest,char * src){
153     char * pesc;
154     while*src ){
155         pesc = escape_ch_table;
156         while*pesc ){
157             if*pesc==*src){
158                 *dest++=ESCAPE_CHAR;
159                 break;
160             }
161             pesc++;
162         }
163         *dest++=*src++;                
164     }    
165     return dest;    
166 }
167 
168 void trim_escape_copy(char * dest,char * src,int size){
169     int last_escape = btsc_FALSE;
170     while( size--){
171         if*src == ESCAPE_CHAR && last_escape != btsc_TRUE){        
172             last_escape = btsc_TRUE    ;
173             src++;
174             continue;
175         }
176         last_escape = btsc_FALSE;
177         *dest++=*src++;        
178     }
179 }
180 
181 int       calcPacketLength(struct btsc_Packet* pkt){
182     int len;
183     int size;
184     struct btsc_Property* ppt;    
185     len = 0;
186     size = pkt->size;
187     while( size--){
188         ppt = pkt->properties[size];    
189         len+=strlen(ppt->name)+strlen(ppt->value);    
190 
191         len+= calcEscapleLength(ppt->name);
192         len+= calcEscapleLength(ppt->value);    
193     }
194     len+= pkt->size*2+1
195     return  len;
196 }
197 
198 
199 int        btsc_Pack(struct btsc_Context*  ctx,struct btsc_Packet* pkt,unsigned char * obuff,int* osize){
200     struct btsc_Property* ppt;
201     int size;
202     int len;
203     unsigned char * buff;
204     char * pbuff;
205     len = calcPacketLength( pkt);
206     /*crc scott 2008.6.16*/
207     if( ctx->crc_check ){
208         len += strlen(CRC_DEFAULT_STRING)+1/*1 is ,*/
209     }
210     /*end crc*/
211     buff = malloc( len );
212     size = pkt->size;
213     pbuff = (char*)buff;
214     *pbuff++=PACKET_HEAD;    
215     /* crc */
216     if( ctx->crc_check ){
217         memcpy(pbuff,CRC_DEFAULT_STRING,strlen(CRC_DEFAULT_STRING));
218         *(pbuff+ strlen(CRC_DEFAULT_STRING))=PROPERTY_DELIMITER;
219         pbuff+=strlen(CRC_DEFAULT_STRING)+1;    
220     }
221     /*end crc*/
222     while( size--){
223         ppt = pkt->properties[size];    
224         pbuff = escape_copy(pbuff,ppt->name);
225         *pbuff++=PAIR_DELIMITER;
226         pbuff = escape_copy(pbuff,ppt->value);
227         if( size ){
228             *pbuff++=PROPERTY_DELIMITER;            
229         }
230     }
231     *pbuff = PACKET_TAIL;
232     /* calc crc sum*/
233     if( ctx->crc_check ){
234         uint16 sum ;
235         char sum_str[4+6];
236         char * crc;
237         sum = crc16_block(buff,pbuff-buff+1);
238         sprintf(sum_str,"CRC=%05d",sum); // must be five chars
239         crc = strstr(buff,CRC_DEFAULT_STRING);
240         memcpy(crc,sum_str,strlen(sum_str));
241     }
242     /*end crc*/
243     if( ctx->tx ){
244         ctx->tx(ctx,buff,len);
245     } 
246     if( obuff && *osize >=len){
247         memcpy( obuff, buff ,len);
248         *osize = len;
249     }
250 
251     free(buff);
252     return btsc_TRUE;    
253 }
254 
255 /* e not in range*/
256 char*     __memchr(char * s,char* e,char c){
257     while( s!=e){
258         if*== c){
259             return s;
260         }        
261         s++;
262     }
263     return btsc_NULL;
264 }
265 
266 int        is_escape_char(char c){
267     return btsc_FALSE;    
268 }
269 
270 /*
271     name: parseProperty
272     desc: 指定内存范围中提取属性  key=>value
273         搜索包含e
274     params:    
275         pkt    --    消息数据包
276         s    --    起始内存地址 
277         e    --    结束地址 ,
278 */
279 void parseProperty(struct btsc_Packet * pkt,char * s,char * e){
280     char * p1,*p2;
281     int n;
282     struct btsc_Property*    ppt;
283     p1 = s ;
284     p2 = e;
285 __REPEAT:    
286     p1 = __memchr(p1,e+1,PAIR_DELIMITER);
287     if( p1 ){
288         if*(p1-1== ESCAPE_CHAR ){
289             p1++;
290             goto __REPEAT;
291         }
292         ppt = malloc( sizeof( struct btsc_Property ));
293         n = p1-s;         
294         ppt->name = malloc( n+1 );
295         memset(ppt->name,0,n+1);        
296         trim_escape_copy(ppt->name,s,n);
297         
298         n =e-p1;
299         ppt->value = malloc( n+1);
300         memset(ppt->value,0,n+1);
301         trim_escape_copy(ppt->value,p1+1,n);
302         
303         btsc_Property_Append(pkt,ppt);
304     }
305 }
306 
307 /*
308 func: crc_check
309 brief: 对数据包进行crc完整性检测
310     提取属性 CRC,填充默认的crc校验和 00000; 校验; 比较
311     crc_check运行完毕, s,e区段的数据被污染(CRC 属性被清除为"CRC=00000")
312 params:
313     pkt     解析出来的数据包 <MSG=XXX,MSG2=XXX2>
314     s        '<'
315     e        '<'
316 return:
317         btsc_TRUE/btsc_FALSE    
318     编码时 CRC属性必须放于属性集的首部
319 */
320 
321 int crc_check(struct btsc_Packet * packet, char *s,char *e){
322     struct btsc_Property * ppt;
323     char * crc;
324     uint16 sum;
325     ppt = btsc_Property_Get(packet,"CRC");
326     if(!ppt){        
327         return -1// no crc sum
328     }
329     if( strlen( ppt->value) != strlen("00000")){
330         return -2;
331     }
332     sum= (uint16) atoi( ppt->value); // 
333     
334     //*e='\0'; // set for strstr() CRC must be existed
335     crc = strstr(s,"CRC");
336     /*substitute default crc sum*/
337     memcpy(crc,CRC_DEFAULT_STRING,strlen(CRC_DEFAULT_STRING));
338     if( sum!=crc16_block(s,e-s+1)){    /*<..> pass into crc */
339         return -3;    /* crc error*/
340     }
341     
342     return btsc_TRUE; 
343 }
344 
345 /*
346     name: parsePacket
347     desc:    分解指定内存到包结构
348             成功分解出包立刻回送到应用接收者 ( btsc_Context::notifier)
349     param:
350         s,e     内存地址 (处e)
351         s ='<'
352         e ='>'
353 ** 缓冲区还需进一步测试,包括缓冲区大小调节, 不完整协议包格式的容错
354 */
355 void     parsePacket(struct btsc_Context* ctx,char * s,char* e){
356     char *p,*p1,*p2;
357     struct btsc_Packet * pkt;
358     if( e-<=1 ){
359         return ;
360     }
361     pkt = btsc_Packet_Alloc(ctx);
362     
363     p1 = s+1;
364     p2 = e-1;
365     p = p1;
366 __REPEAT:    
367     p = __memchr(p,e,PROPERTY_DELIMITER);
368     if( p ){
369         if*(p-1)==ESCAPE_CHAR){
370             p = p+1;
371             goto __REPEAT;
372         }
373         parseProperty(pkt,p1,p-1);
374         p1 = ++p;
375         goto __REPEAT;
376     }
377     /*allow one property reside in*/
378     parseProperty(pkt,p1,e-1);
379     /*2008.6.16 scott add crc check*/
380     if( ctx->crc_check ){
381         if( crc_check(pkt,s,e)==btsc_FALSE ){ /*crc check error*/
382             btsc_Packet_Free(pkt);    
383             return ;
384         }
385     }
386     /*end crc check*/
387     if( ctx->notifier ){
388         if(ctx->notifier(pkt)){ /* nonzero value, delete internal*/
389             btsc_Packet_Free(pkt);            
390         }
391     }else{
392        btsc_Packet_Free(pkt);    
393     }
394 }
395 
396 void    btsc_Parse(struct btsc_Context* ctx, char * data,int size){
397     int len ;
398 _RESTART:
399     while( size ){
400         len = ctx->recv_cached_capacity - ctx->recv_size;
401         if( len >0){ 
402             if( size <= len){
403                 len = size;
404                 size = 0;
405             }else{
406                 size-=len;
407             }
408             memcpy( ctx->recv_buff+ctx->recv_size,data,len);
409             ctx->recv_size+=len;
410             data+=len;
411         }    
412         
413         {
414             char * p1,*p2;            
415 _RESCAN:            
416             p1 = ctx->recv_buff;
417 _RESCAN_HEAD:             
418             p1 = __memchr(p1,ctx->recv_buff+ctx->recv_size,PACKET_HEAD);            
419             if!p1 ){ 
420                 ctx->recv_size =0;
421                 if( size ){
422                     goto _RESTART;
423                 }else{
424                     return ;//scott by 2007.06.15 add 
425                 }
426             }
427             if( p1>ctx->recv_buff && *(p1-1)==ESCAPE_CHAR){ /* "\<" */
428                 p1++;
429                 goto _RESCAN_HEAD;    
430             }
431             
432             /*move backward*/
433             ctx->recv_size -=(p1-ctx->recv_buff);
434             memmove(ctx->recv_buff,p1, ctx->recv_size);
435             p1=ctx->recv_buff;
436             p2 = p1+1;
437 _RESCAN_TAIL:            
438             p2 = __memchr(p2,ctx->recv_buff+ctx->recv_size,PACKET_TAIL);
439             if!p2 ){
440                 if( ctx->recv_size == ctx->recv_cached_capacity ){
441                     ctx->recv_size  = 0
442                 }
443                 goto _RESTART;
444             }
445             if*(p2-1== ESCAPE_CHAR ){
446                 p2++;
447                 goto _RESCAN_TAIL;    
448             }
449             
450             parsePacket(ctx,p1,p2);
451             ctx->recv_size -=p2-p1+1;
452             if( ctx->recv_size ){
453                 memmove(ctx->recv_buff,p2+1,ctx->recv_size);
454                 goto _RESCAN; 
455             }             
456         }        
457     }
458 }
459 
460 /*   debug */
461 #ifdef _DEBUG
462 void tx(unsigned char * data,int len);
463 void notifier(struct btsc_Packet* packet);
464 /*初始化上下文, tx=发送处理函数,notifier=接收函数*/
465 //struct btsc_Context c={tx:tx,notifier:notifier};
466 struct btsc_Context c={tx,notifier};
467 
468 /*测试数据接收并解析*/
469 void rx(unsigned char * buff,int len){    
470      char * msg="<MSG=HELLO,NAME=SCOTT>"
471                  "<MSG2=HELLO2,NAME2=SCOTT2>"
472                  "<MSG3=HELLO3,NAME3=SCOTT3>"/*simulating data*/
473     //int len = strlen(msg);
474     btsc_Parse(&c,buff,len);
475 }
476 /*发送处理过程*/
477 void tx(struct btsc_Context*  ctx,unsigned char * buff,int len){    
478     char *outmsg = malloc(1024*10);
479     memset(outmsg,0,1024*10);
480     memcpy(outmsg,buff,len);
481     printf("encode str: %s\n",outmsg);
482     free(outmsg);
483     btsc_Parse(&c,buff,len);
484 }
485 
486 void notifier(struct btsc_Packet* packet){
487     struct btsc_Property * ppt;
488     ppt = btsc_Property_Get(packet,"MSG");
489     if(ppt)
490         printf("property get: MSG=>%s\n",ppt->value);
491     /*遍历包内属性参数*/
492     BTSC_FOREACH(packet,ppt);
493     printf("packet: %s=>%s\n",ppt->name,ppt->value);
494     BTSC_END_FOREACH();
495 }
496 
497 int test_main(){
498     int r;
499     /*optional*/
500     c.recv_cached_capacity = 1024/*初始化接收缓冲区大小 byte*/
501     c.packet_cached_size = 5;    /*消息包缓冲属性个数*/
502     btsc_init(&c);            /*上下文初始化*/
503     //c.crc_check = 0;
504     puts("test rx()");
505 //    rx();    /*接*/
506     puts("escape testing");    
507     do{
508         /*构造消息包,并完成发送*/
509         BTSC_PACKET_BEGIN(&c);
510         BTSC_NEW_PROPERTY("MSG","calling");
511 
512         BTSC_PACKET_END();    
513     //    usleep(1000*50);
514         printf(">>seq:%d\n",r);
515     }while(0);
516         
517     btsc_cleanup(&c);    
518     
519     return 0;
520 }
521 
522 
523 #endif
524 

只有注册用户登录后才能发表评论。
网站导航: 博客园   IT新闻   BlogJava   博问   Chat2DB   管理