C strtok test


strtok 함수는 파싱할때 사용하기 좋은 함수이다.
delimiter를 정하면 token 단위로 파싱 할 수 있다.
아래는 함수 테스트를 위한 코드

--------------------------------------------------------

/**********************************************************
*
*        Test code for testing strtok
*
***********************************************************/
#include <stdio.h>
#include <string.h>
#include <stdlib.h>

#define CR \r
#define LF \n

#define SHOWALL 0

//#define REGISTER 0
//#define INVITE 1

#define IS_INVITE(val) strcmp(val,"INVITE") == 0
#define IS_CALLID(val) strcmp(val,"Call-ID") == 0 || strcmp(val, "CALL-ID") == 0 || strcmp(val, "call-id") == 0
#define IS_FROM(val) strcmp(val,"From") == 0 || strcmp(val,"FROM") == 0
#define IS_TO(val) strcmp(val,"To") == 0 || strcmp(val,"TO") == 0


enum SIP_METHOD{
REGISTER,
INVITE,
ACK,
CANCEL,
BYE,
OPTIONS
};


int sipd_parser(char *a_msg);
int getRequestType(char *method);
void process_INVITE_MSG();
void sipd_parse_header(char *a_msg);


void process_INVITE_MSG(){
printf("is INVITE!!!\n");
}

int sipd_parse_startLine(char *startline){
//printf("startlIne : %s\n",startline);

int methodType;
char *token;
char *ptr;

// check if start with 'SIP/2.0'
if( strncmp(startline,"SIP",3) == 0 ){
strtok_r(startline," ",&ptr);

// getMethod or status
token = strtok_r(NULL, " ",&ptr);
}
else{
token = strtok_r(startline," ",&ptr);
}
methodType = getMethodType(token);


// get myuri
strtok_r(NULL, ":",&ptr);
token = strtok_r(NULL, "@",&ptr);
printf("myuri : %s\n",token);

// get host uri
token = strtok_r(NULL, ":",&ptr);
printf("host uri : %s\n",token);

// get host port
token = strtok_r(NULL, " ",&ptr);
printf("host port : %s\n",token);

//printf("startline : %s\n",startline);

/*
* If need, do parse other elements here.
*/

return methodType;
}

int getMethodType(char *method){

int rv;

printf("recv method = %s\n",method);

if(method[0] >= 49 && method[0] <= 57){
rv = atoi(method);
printf("method = %d\n",rv);
}
//else if( (method[0] >= 65 && method[0] <= 90) || (method[0] >= 97 && method[0] <= 122) ){

else{
switch(method[0]){
case 'R': 
printf("REGISTER!!\n");
break;
case 'I': if(IS_INVITE(method)) rv = INVITE;
printf("INVITE!!\n");
break;
case 'A':
break;
case 'C':
break;
case 'B':
break;
case 'O':
break;
}/*
if( method[0] == 'I' ){
if( strcmp(method,"INVITE") == 0){
rv = INVITE;
}
}*/
}
// status response



return rv;
}

void sipd_parse_header(char *a_msg){
char *token = NULL;
char delim[] = " :\r\n";
//char tag_delim = "tag=";
char *msg;
short flag=0;
char *subprt;

msg = (char*)malloc(sizeof(a_msg));
strcpy(msg,a_msg);

//printf("token %s\n",msg);

token = strtok_r(msg,delim, &subprt);

//printf("header %s\n",token);

while(token != NULL){
if( IS_CALLID(token) ){
token = strtok_r(NULL, delim, &subprt);
//if( flag && *token != ' ' && *token != ':' ){
//strcpy(sipd_message->callid->id, token);
printf("call-id : %s\n",token);
break;
}
else if( IS_FROM(token) ){
strtok_r(NULL, "=", &subprt);
token = strtok_r(NULL, "\r\n", &subprt);
//strcpy(sipd_message->callid->id, token);
printf("from tag : %s\n",token);
}
else if( IS_TO(token) ){
strtok_r(NULL, "=", &subprt);
token = strtok_r(NULL, "\r\n", &subprt);
//strcpy(sipd_message->callid->id, token);
printf("to tag : %s\n",token);
}
token = strtok_r(NULL, delim, &subprt);
}
}



int sipd_parser(char *a_msg){
char *token = NULL;
char delim[] = "\r\n";
char msg[strlen(a_msg)];
int methodType;
char *ptr;

strcpy(msg,a_msg);//,sizeof(a_msg));

#if SHOWALL
printf("msg : %s\n",msg);
printf("a_msg : %s\n",a_msg);
#endif

token = strtok_r(msg, delim, &ptr);

methodType = sipd_parse_startLine(token);

while( (token = strtok_r(NULL, delim, &ptr)) != NULL){
/*token = strtok_r(NULL, delim, &ptr);
if(token == NULL) break;*/
#if SHOWALL
printf("in Parser %s\n",token);
#endif
sipd_parse_header(token);
}

//printf("after getMethod a_msg : %s\n",msg);
//sipd_parse_header(msg);

switch(methodType){
case 0: // REGISTER
break;
case 1: // INVITE
process_INVITE_MSG();
break;
case 2: // ACK
break;
case 3: // CANCEL
break;
case 4: // BYE
break;
case 5: // OPTIONS
break;
default:
if( methodType >= 100 && methodType < 200 ){
printf("100~\n");
}
else if( methodType >= 200 && methodType < 300 ){
printf("200~\n");
}
else if( methodType >= 300 && methodType < 400 ){
printf("300~\n");
}
else if( methodType >= 400 && methodType < 500 ){
printf("400~\n");
}
else if( methodType >= 500 && methodType < 600 ){
}
else if( methodType >= 600 && methodType < 700 ){
}
break;
}
return 0;
}

int main(){
char *token = NULL;
char s1[] = "SIP/2.0 401 Unauthorized sip:0476504146@90.96.10.10:5060 SIP/2.0\r\n\
Max-Forwards: 70\r\n\
Call-ID: f7c5f7c7d246fcdcab60ca5e8fa44a2b@90.96.10.21\r\n\
From: 0476504121 <sip:0476504121@90.96.10.10:5060>;tag=336bf603e6f94a8\r\n\
To: 0476504146 <sip:0476504146@90.96.10.10:5060>";//;tag=45645654345sdfgsas\r\n";
char s2[] = " :@CRLF";

printf("=== Message ====================\n%s\n\n",s1);

sipd_parser(s1);

return 0;
}

댓글 없음:

댓글 쓰기

안녕하세요 :)