2017-12-26 27 views
0

私はCoPプロトコルを実装する単純なクライアントとシンプルなサーバーでライブラリを使用してRaspbianのRaspbianでlibcoap-dev-1ライブラリを使用しています。私は働いているクライアントと稼働中のサーバーを持っていて、現在はサーバーを変更して、クエリ文字列でURIを受け入れ、URIのクエリ文字列を取得できるようにしようとしています。libcoap coap serverでGETレスポンスハンドラURIへのクエリの追加にアクセスする方法は?

私が現在テストしているURIはで、クエリパラメータを持っています.?の後にitem=1があります。

サーバー内のリクエストハンドラは、JSONテキストとしてクライアントに返された応答をテストするスタブである次の関数です。これはうまく動作し、クライアントはJSONテキストを受け取り、それを解析するためにFast JSONライブラリを使用することができます。関数の終了時に

// header for the libcoap library. it should be in /usr/include/coap 
#include <coap/coap.h> 

/* 
* The resource handler which the libcoap library will invoke when the registered 
* URI is specified. 
*/ 
static void 
hello_handler(coap_context_t *ctx, struct coap_resource_t *resource, 
       const coap_endpoint_t *local_interface, coap_address_t *peer, 
       coap_pdu_t *request, str *token, coap_pdu_t *response) 
{ 
     static int iCount = 0; 
     unsigned char buf[3]; 
     const char* response_data  = "{\"device\": \"DEV-01-123\", \"item\" : %d }"; 
     char response_buf[256] = {0}; 

     response->hdr->code   = COAP_RESPONSE_CODE(205); 
     coap_add_option(response, COAP_OPTION_CONTENT_TYPE, coap_encode_var_bytes(buf, COAP_MEDIATYPE_TEXT_PLAIN), buf); 

     sprintf (response_buf, response_data, iCount); 
     coap_add_data (response, strlen(response_buf), (unsigned char *)response_buf); 
     iCount++; 

     printf (" request %s\n", resource->uri.s); 
} 

printf()クエリ部分なしURIを印刷します。したがって、印刷されるのはhelloで、hello?item=1ではありません。

私の質問は、クライアントが送信しているURIのクエリ部分にどのようにアクセスできますか?

+0

あなたがlibcoapのどのバージョンを使用していますか? – jwdonahue

+0

@jwdonahue私はそれが1.0.xだと信じています。sudo apt-get install libcoap-1-0-devを使って 'apt-get'でインストールしました。私は現時点でPiにアクセスできない。その違いは何ですか? –

+0

これは、 'if(request!= NULL &&(option)'の判定で 'coap_check_option()'を使って、131行目でhttps://github.com/obgm/libcoap/blob/develop/examples/contiki/server.cを見つけました。 === 0){' –

答えて

0

libcoapサーバとクライアントを作成する機能には、URIとURIクエリ情報をCoAP要求に/から書式設定して取得するためのいくつかのステップが必要です。

完全なサンプルアプリケーションclient.cとserver.cは、私のGitHubリポジトリhttps://github.com/RichardChambers/raspberrypi/tree/master/coapにあります。

サーバー側では、メッセージハンドラは、coap_pdu_t構造化要求オブジェクトのオプションを反復処理するために、オプションイテレータのcoap_opt_iterator_t構造体オブジェクトを使用します。反復処理中に、サーバーは、照会引数、通常はキーワード等価値のペアを含むタイプCOAP_OPTION_URI_QUERYのオプションを探します。次のように

ので、投稿、質問の機能hello_handler()は、URIのクエリーアイテムのリストを取得するためにヘルパー関数を書き換えることができます。クライアント側では

/* 
* The following helper function, printQueryOption(), is used to 
* iterate over the list of options looking for query type options 
* to the base URI. This is analogous to a web URL that contains 
* a question mark followed by options such as: 
* http://www.server.com/hello?type=1,id=2345 
* 
* We will return a value of 1 (true) if we found something or a value 
* of 0 (false) if we do not. 
*/ 
static int 
printQueryOption (coap_pdu_t *request, coap_opt_iterator_t * popt_iter) 
{ 
     int iRet = 0; 
     coap_opt_t *option; 

     // iterate over the options looking for queries. If we find one 
     // then print it and return a value of 1, true, to indicate we 
     // found one. If we don't find any then return the default value 
     // of 0, false. 
     while (option = coap_option_next(popt_iter)) { 
       // found an option, is it a query option or not. 
       if (popt_iter->type != COAP_OPTION_URI_QUERY) continue; 
       // it is a query option so print out the query text. 
       char xBuff[128] = {0}; 
       strncpy (xBuff, COAP_OPT_VALUE(option), COAP_OPT_LENGTH(option)); 
       printf (" option len %d\n   %s \n", COAP_OPT_LENGTH(option), xBuff); 

       // indicate that we found a query option. 
       iRet = 1; 
       break; 
     } 

     return iRet; 
} 

/* 
* The resource handler which the libcoap library will invoke when the registered 
* URI is specified. This is a simple request handler which will just display some 
* of the information from the request. 
*/ 
static void 
hello_handler(coap_context_t *ctx, struct coap_resource_t *resource, 
       const coap_endpoint_t *local_interface, coap_address_t *peer, 
       coap_pdu_t *request, str *token, coap_pdu_t *response) 
{ 
     static int iCount = 0; // a simple count to provide some kind of response data. 
     unsigned char buf[3]; 
     const char* response_data  = "{\"device\": \"DEV-01-123\", \"item\" : %d }"; 
     char response_buf[256] = {0}; 

     // generate a response to this request. we have a hard coded JSON text that 
     // we are using as a stub for testing. 
     response->hdr->code   = COAP_RESPONSE_CODE(205); 
     coap_add_option(response, COAP_OPTION_CONTENT_TYPE, coap_encode_var_bytes(buf, COAP_MEDIATYPE_TEXT_PLAIN), buf); 

     sprintf (response_buf, response_data, iCount); 
     coap_add_data (response, strlen(response_buf), (unsigned char *)response_buf); 
     iCount++; // this count is some type of varying data so that we can see things are working. 

     if (request != NULL) { 
       // there is a request URI so lets print out the base URI and then 
       // iterate over the options looking for the Query type options. 
       coap_opt_iterator_t opt_iter; 

       printf (" request %s\n", resource->uri.s); 
       coap_option_iterator_init (request, &opt_iter, COAP_OPT_ALL); 

       // iterate over the options of the request printing out any 
       // query text that may exist. 
       while (printQueryOption (request, &opt_iter)); 
     } else { 
       printf (" request - NONE\n"); 
     } 
} 

を、私たちは、クエリに我々を追加し、私たちの要求を構築します仕えるように、これらのステートメントは、引数またはクエリオプションのセットで、特定のURIにCoAP要求を作成

coap_split_uri(server_uri, strlen(server_uri), &uri); 
request   = coap_new_pdu(); 
request->hdr->type = COAP_MESSAGE_CON; 
request->hdr->id = coap_new_message_id(ctx); 
request->hdr->code = get_method; 

printf (" Request URI: path %d %s\n", uri.path.length, uri.path.s); 

coap_add_option(request, COAP_OPTION_URI_PATH, uri.path.length, uri.path.s); 
sprintf (server_query, "item=%d", iItem); 
coap_add_option(request, COAP_OPTION_URI_QUERY, strlen(server_query), server_query); 
printf ("   Query: len %d %s\n", strlen(server_query), server_query); 
sprintf (server_query, "device=%s", aszDevName); 
coap_add_option(request, COAP_OPTION_URI_QUERY, strlen(server_query), server_query); 
printf ("   Query: len %d %s\n", strlen(server_query), server_query); 
sprintf (server_query, "tempo=%s", aszTempoName); 
coap_add_option(request, COAP_OPTION_URI_QUERY, strlen(server_query), server_query); 
printf ("   Query: len %d %s\n", strlen(server_query), server_query); 

:のように機能coap_add_option()の一連の呼び出しと要求に含めますrのURIのハンドラは、特定の応答を要求に返すことができます。この例で使用される変数は、ハード以下のような値を使用して符号化される。

char *aszDevName = "DEV-01-203"; 
char *aszTempoName = "TEMPO-12345"; 
int iItem = 5; 

const char*  server_uri = "coap://127.0.0.1/hello"; 

2つのサンプルプログラムは、最初のサーバを起動する2つの別々の端末のウィンドウで実行することができます。 URIを「hello」、第2のURIを「goodbye」、第3回URIを「hello」としてクライアントを3回試行すると、次の出力が表示されます。サーバーから

[email protected]:~/Documents/raspberrypi/coap $ ./server 
request hello 
    option len 6 
     item=5 
    option len 17 
     device=DEV-01-203 
    option len 17 
     tempo=TEMPO-12345 
request hello 
    option len 6 
     item=5 
    option len 17 
     device=DEV-01-203 
    option len 17 
     tempo=TEMPO-12345 

クライアントの端末ウィンドウから:

[email protected]:~/Documents/raspberrypi/coap $ ./client 
Request URI: path 5 hello 
     Query: len 6 item=5 
     Query: len 17 device=DEV-01-203 
     Query: len 17 tempo=TEMPO-12345 
Received: {"device": "DEV-01-123", "item" : 0 } -> item = 0 
[email protected]:~/Documents/raspberrypi/coap $ ./client goodbye 
Request URI: path 7 goodbye 
     Query: len 6 item=5 
     Query: len 17 device=DEV-01-203 
     Query: len 17 tempo=TEMPO-12345 

COAP_RESPONSE_CLASS() unknown. 
[email protected]:~/Documents/raspberrypi/coap $ ./client 
Request URI: path 5 hello 
     Query: len 6 item=5 
     Query: len 17 device=DEV-01-203 
     Query: len 17 tempo=TEMPO-12345 
Received: {"device": "DEV-01-123", "item" : 1 } -> item = 1 
[email protected]:~/Documents/raspberrypi/coap $ 
関連する問題