Advertisement
Guest User

server

a guest
Aug 17th, 2016
187
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 92.14 KB | None | 0 0
  1.  
  2. /**
  3. * @todo Asenkron ve blocking mod için linda ve client tarafı eş zamanlı dinlenecek
  4. * @todo PoA optionları bind ve parse edilecek
  5. * @todo Doxy etiketleri yazılacak
  6. * @todo Gerekli commentler girilecek
  7. * @todo Fonksiyon dönüşlerinde gerekli return checkleri konacak
  8. * @todo Eski loglar silinecek ve yeni loglar (DEBUG, Info ve ERR ) eklenecek
  9. * @todo Lindaya atılıtken kullanılan Linda_put processi, linda_proc.c altındaki fonsiyon kullanılarak yapılacak
  10. * @todo Filte criteria içindeki cur_node1 her optiondan sonra aramak yerine, while döngüsüne bağlanacak
  11. * @todo State saklama yapılacak
  12. * @todo Signal yedikten sonra yapılacak işlemler tekrar düzenlenecek
  13. * @todo Protocol check yapılarak error code dönülecek client tarafına
  14. * @todo Request exp_time kontrol edilecek ve paket işlenmeden düşürme işlemi gerekirse response tarafı ayarlanacak
  15. * @todo 12 numalaralı Content type option ı kontrol edilerek Json veya XML ise ona göre fonksiyolar yazılacak ve cağırılacak
  16. * @todo Xmltoflat yerine Branching modülüne gönderim yapılacak
  17. * @todo Değişken tanımları ve yerleri gözden geçirilecek
  18. * @todo Mollac ve free işlemleri gözden geçirilecek
  19. * @todo Request function operation switch-case yapılacak, default deger olarak ERR donulecek
  20. * @todo Print_coap_msge fonksiyoni içindeki printfler sonunda "\n" olmayan log makroları ile değiştirilecek
  21. * @todo xml ve json mesaj işleme bölümü ayrı bir dosyaya alınacak
  22. * @todo xml ve json mesaj build işlemleri ayrı bir dosyaya alınacak ve include olarak eklenecek
  23. *
  24. * @brief Source file for the FreeCoAP server library
  25. */
  26. #include <stdlib.h>
  27. #include <stdio.h>
  28. #include <string.h>
  29. #include <stdint.h>
  30. #include <time.h>
  31. #include <errno.h>
  32. #include <unistd.h>
  33. #include <fcntl.h>
  34. #include <dirent.h>
  35. #include <sys/types.h>
  36. #include <sys/stat.h>
  37. #include <arpa/inet.h>
  38. #include <sys/select.h>
  39. #include <sys/timerfd.h>
  40. #include <linux/types.h>
  41. #include <stdbool.h>
  42. #include "coap_server.h"
  43. #include "coap_log.h"
  44. #include <glib.h>
  45. #include <libxml/parser.h>
  46. #include <libxml/tree.h>
  47. #include <net/if.h>
  48. #include <signal.h>
  49. #include "../linda/m2m_client.h"
  50. #include "resources.h"
  51. #include "linda_proc.h"
  52. #include "flatten.h"
  53. #include "cell_data.h"
  54. #include "xml_flat.h"
  55. #include <glib-object.h>
  56. #include <json-glib/json-glib.h>
  57. #include "json_flat.h"
  58. #include "struct_send.h"
  59. #include <time.h>
  60. #include "msg_parser.h"
  61. #include "isValid.h"
  62. #define COAP_SERVER_ACK_TIMEOUT_SEC  2  /**< Minimum delay to wait before retransmitting a confirmable message */
  63. #define COAP_SERVER_MAX_RETRANSMIT 4  /**< Maximum number of times a confirmable message can be retransmitted */
  64. #define DEBUG DBG
  65. #ifdef COAP_DTLS_EN
  66. #define COAP_SERVER_DTLS_MTU  COAP_MSG_MAX_BUF_LEN  /**< Maximum transmission unit excluding the UDP and IPv6 headers */
  67. #define COAP_SERVER_DTLS_RETRANS_TIMEOUT 1000  /**< Retransmission timeout (msec) for the DTLS handshake */
  68. #define COAP_SERVER_DTLS_TOTAL_TIMEOUT 60000 /**< Total timeout (msec) for the DTLS handshake */
  69. #define COAP_SERVER_DTLS_NUM_DH_BITS  1024  /**< DTLS Diffie-Hellman key size */
  70. #define COAP_SERVER_DTLS_PRIORITIES  "PERFORMANCE:-VERS-TLS-ALL:+VERS-DTLS1.0:SERVER_PRECEDENCE"
  71. /**< DTLS priorities */
  72. #endif
  73. #ifdef MALLOC_TRACE
  74. #include <mcheck.h>
  75. #endif
  76. #define MAX_A(A, B) ((A) > (B) ? (A) : (B) )
  77. int linda_fd;
  78. extern char *linda_ip;
  79. extern char *linda_port;
  80. GHashTable* hash;
  81. GHashTable* hash_pri_to_coap_code;
  82. GHashTable* hash_pri_to_coap_detail;
  83. GHashTable* hash_table_struct;
  84. heap_table_t *heap = NULL;
  85. GHashTable* hash_coap_uri_query;
  86. GHashTable* hash_coap_conf;
  87. char *rqi_hash_key;
  88. extern void *linda;
  89. extern int log_level;
  90. struct ifreq ifr;
  91. int ret = 0;
  92. struct {
  93.         char *poa_port[5];
  94.         char *poa_host;
  95.         char *poa_uri[20];
  96.         char json_poa[50];
  97.         char *dest_uri[20];
  98.         int *xmlBuffSize;
  99. }coap_server_glb;
  100. int group1[]={BRANCHING_GROUP, -1};
  101. char *config_name[5]={"XML_NAME_SPACE","XML_NAME_SPACE_URL","LINDA_IP","LINDA_PORT", NULL};
  102. char *config_value[4]={ NULL, NULL,NULL,NULL};
  103. void last_wish(){
  104.         LOG(3, "Process kapanıyor. Bellekler free edilecek ve socketler kapatılacak.");
  105.         if(heap){
  106.                 heap_free((void**)&heap);
  107.                 LOG(3,"Heap free yapıldı.");
  108.         }
  109.         else {
  110.                 LOG(3,"Heap önceden free edilmiş");
  111.         }
  112.         if(linda){
  113.                 free(linda);
  114.                 LOG(3, "Linda bağlantısı kapatıldı.");
  115.         }
  116.         else {
  117.                 LOG(3,"Linda bağlantısı önceden kapatılmış");
  118.         }
  119. }
  120.  
  121. /*
  122.   @brief remove the key value from the string
  123.  
  124.   @param String pointer
  125.   @param Key value pointer
  126.  */
  127. int strRemove(char *src,char *key)
  128. {
  129.         while( *src )
  130.         {
  131.                 char *k=key,*s=src;
  132.                 while( *k && *k==*s ) ++k,++s;
  133.                 if( !*k )
  134.                 {
  135.                         while( *s ) *src++=*s++;
  136.                         *src=0;
  137.                         return 1;
  138.                 }
  139.                 ++src;
  140.         }
  141.         return 0;
  142. }
  143. static int print_coap_msge(const char *str, coap_msg_t *msg)
  144. {
  145.  
  146.         coap_msg_op_t *op = NULL;
  147.         unsigned num = 0;
  148.         unsigned len = 0;
  149.         unsigned i = 0;
  150.         unsigned j = 0;
  151.         char *token = NULL;
  152.         char *val = NULL;
  153.         coap_log_level_t log_level = 0;
  154.  
  155.         log_level = coap_log_get_level();
  156.         if (log_level < COAP_LOG_INFO)
  157.         {
  158.                 return (0);
  159.         }
  160.         printf("%s\n", str);
  161.         printf("ver:         0x%02x\n", coap_msg_get_ver(msg));
  162.         printf("type:        0x%02x\n", coap_msg_get_type(msg));
  163.         printf("token_len:   %d\n", coap_msg_get_token_len(msg));
  164.         printf("code_class:  %d\n", coap_msg_get_code_class(msg));
  165.         printf("code_detail: %d\n", coap_msg_get_code_detail(msg));
  166.         printf("msg_id:      0x%04x\n", coap_msg_get_msg_id(msg));
  167.         printf("token:      ");
  168.         token = coap_msg_get_token(msg);
  169.         for (i = 0; i < coap_msg_get_token_len(msg); i++)
  170.         {
  171.                 printf(" 0x%02x", (unsigned char)token[i]);
  172.         }
  173.         printf("\n");
  174.         op = coap_msg_get_first_op(msg);
  175.         while (op != NULL)
  176.         {
  177.                 num = coap_msg_op_get_num(op);
  178.                 len = coap_msg_op_get_len(op);
  179.                 val = coap_msg_op_get_val(op);
  180.                 printf("op[%u].num:   %u\n", j, num);
  181.                 printf("op[%u].len:   %u\n", j, len);
  182.                 printf("op[%u].val:  ", j);
  183.                 for (i = 0; i < len; i++)
  184.                 {
  185.                         printf(" 0x%02x", (unsigned char)val[i]);
  186.                 }
  187.                 printf("\n");
  188.                 op = coap_msg_op_get_next(op);
  189.                 j++;
  190.         }
  191.         printf("payload:     ");
  192.         /*  primitive.content = coap_msg_get_payload(msg);
  193.          *  for (i = 0; i < coap_msg_get_payload_len(msg); i++)
  194.          *  {
  195.          *  printf("%c", primitive.content[i]);
  196.          *  } */
  197.         printf("\n");
  198.         printf("payload_len: %u\n", (unsigned int)coap_msg_get_payload_len(msg));
  199.         fflush(stdout);
  200.         return 0;
  201. }
  202. /****************************************************************************************************
  203.  *  coap_server_path  *
  204.  ****************************************************************************************************/
  205. /*
  206.   @brief Allocate a URI path structure
  207.  
  208.   @param[in] str String representation of a URI path
  209.  
  210.   @returns New URI path structure
  211.   @retval NULL Out-of-memory
  212.  */
  213. static coap_server_path_t *coap_server_path_new(const char *str)
  214. {
  215.         coap_server_path_t *path = NULL;
  216.         path = (coap_server_path_t *)malloc(sizeof(coap_server_path_t));
  217.         if (path == NULL)
  218.         {
  219.                 return NULL;
  220.         }
  221.         path->str = strdup(str);
  222.         if (path->str == NULL)
  223.         {
  224.                 free(path);
  225.                 return NULL;
  226.         }
  227.         path->next = NULL;
  228.         return path;
  229. }
  230. /*
  231.   @brief Free a URI path structure
  232.  
  233.   @param[in,out] path Pointer to a URI path structure
  234.  */
  235. static void coap_server_path_delete(coap_server_path_t *path)
  236. {
  237.         free(path->str);
  238.         free(path);
  239. }
  240. /*
  241.  @brief Initialise a URI path list structure
  242.  
  243.  @param[out] list Pointer to a URI path list structure
  244.  */
  245. static void coap_server_path_list_create(coap_server_path_list_t *list)
  246. {
  247.         memset(list, 0, sizeof(coap_server_path_list_t));
  248. }
  249. /*
  250.  @brief Deinitialise a URI path list structure
  251.  
  252.  @param[in,out] list Pointer to a URI path list structure
  253.  */
  254. static void coap_server_path_list_destroy(coap_server_path_list_t *list)
  255. {
  256.         coap_server_path_t *prev = NULL;
  257.         coap_server_path_t *path = NULL;
  258.         path = list->first;
  259.         while (path != NULL)
  260.         {
  261.                 prev = path;
  262.                 path = path->next;
  263.                 coap_server_path_delete(prev);
  264.         }
  265.         memset(list, 0, sizeof(coap_server_path_list_t));
  266. }
  267. /*
  268.  @brief Add a URI path to a URI path list structure
  269.  
  270.  @param[in,out] list Pointer to a URI path list structure
  271.  @param[in] str String representation of a URI path
  272.  
  273.  @returns Operation status
  274.  @retval 0 Success
  275.  @retval <0 Error
  276.  */
  277. static int coap_server_path_list_add(coap_server_path_list_t *list, const char *str)
  278. {
  279.         coap_server_path_t *path = NULL;
  280.         path = coap_server_path_new(str);
  281.         if (path == NULL)
  282.         {
  283.                 return -ENOMEM;
  284.         }
  285.         if (list->first == NULL)
  286.         {
  287.                 list->first = path;
  288.                 list->last = path;
  289.         }
  290.         else
  291.         {
  292.                 list->last->next = path;
  293.                 list->last = path;
  294.         }
  295.         return 0;
  296. }
  297. /*
  298.  @brief Search a URI path list structure for a URI path
  299.  
  300.  @param[in] list Pointer to a URI path list structure
  301.  @param[in] str String representation of a URI path
  302.  
  303.  @returns Comparison value
  304.  @retval 0 The URI path list structure does not contain the URI path
  305.  @retval 1 The URI path list structure does contain the URI path
  306.  */
  307. static int coap_server_path_list_match(coap_server_path_list_t *list, const char *str)
  308. {
  309.         coap_server_path_t *path = NULL;
  310.         path = list->first;
  311.         while (path != NULL)
  312.         {
  313.                 coap_log_debug("Comparing URI path: '%s' with list URI path: '%s'", str, path->str);
  314.                 if (strcmp(path->str, str) == 0)
  315.                 {
  316.                         coap_log_debug("Matched URI path: '%s' with list URI path: '%s'", str, path->str);
  317.                         return 1;
  318.                 }
  319.                 path = path->next;
  320.         }
  321.         return 0;
  322. }
  323. #ifdef COAP_DTLS_EN
  324. /****************************************************************************************************
  325.  * coap_server_trans_dtls  *
  326.  ****************************************************************************************************/
  327. /*
  328.  @brief Listen for a packet from the client with a timeout
  329.  
  330.  @param[in] trans Pointer to a transaction structure
  331.  @param[in] ms Timeout value in msec
  332.  
  333.  @returns Operation status
  334.  @retval 1 Success
  335.  @retval 0 Timeout
  336.  @retval <0 Error
  337.  */
  338. static int coap_server_trans_dtls_listen_timeout(coap_server_trans_t *trans, unsigned ms)
  339. {
  340.         coap_server_t *server = NULL;
  341.         struct timeval tv = {0};
  342.         fd_set read_fds = {{0}};
  343.         int ret = 0;
  344.         server = trans->server;
  345.         tv.tv_sec = ms / 1000;
  346.         tv.tv_usec = (ms % 1000) * 1000;
  347.         while (1)
  348.         {
  349.                 FD_ZERO(&read_fds);
  350.                 FD_SET(server->sd, &read_fds);
  351.                 ret = select(server->sd + 1, &read_fds, NULL, NULL, &tv);
  352.                 if (ret == -1)
  353.                 {
  354.                         return -errno;
  355.                 }
  356.                 if (ret == 0)
  357.                 {
  358.                         return 0; /* timeout */
  359.                 }
  360.                 if (FD_ISSET(server->sd, &read_fds))
  361.                 {
  362.                         return 1; /* success */
  363.                 }
  364.         }
  365. }
  366. /*
  367.  @brief Receive data from the client
  368.  
  369.  This is a call-back function that the
  370.  GnuTLS library uses to receive data.
  371.  
  372.  @param[in,out] data Pointer to a transaction structure
  373.  @param[out] buf Pointer to a buffer
  374.  @param[in] len Length of the buffer
  375.  
  376.  @returns Number of bytes received or error
  377.  @retval 0 Number of bytes received
  378.  @retval -1 Error
  379.  */
  380. static ssize_t coap_server_trans_dtls_pull_func(gnutls_transport_ptr_t data, void *buf, size_t len)
  381. {
  382.         coap_server_trans_t *trans = NULL;
  383.         struct sockaddr_in6 client_sin = {0};
  384.         coap_server_t *server = NULL;
  385.         socklen_t client_sin_len = 0;
  386.         ssize_t num = 0;
  387.         trans = (coap_server_trans_t *)data;
  388.         server = trans->server;
  389.         client_sin_len = sizeof(client_sin);
  390.         errno = 0;
  391.         num = recvfrom(server->sd, buf, len, MSG_PEEK, (struct sockaddr *)&client_sin, &client_sin_len); /* peek data */
  392.         if (num == -1)
  393.         {
  394.                 return -1;
  395.         }
  396.         if ((client_sin_len != trans->client_sin_len)
  397.                         || (memcmp(&client_sin, &trans->client_sin, trans->client_sin_len) != 0))
  398.         {
  399.                 gnutls_transport_set_errno(trans->session, EAGAIN);
  400.                 return -1;
  401.         }
  402.         return recvfrom(server->sd, buf, num, 0, (struct sockaddr *)&client_sin, &client_sin_len); /* consume data */
  403. }
  404. /*
  405.  @brief Wait for receive data from the client
  406.  
  407.  This is a call-back function that the GnuTLS
  408.  library uses to wait for receive data.
  409.  
  410.  @param[in,out] data Pointer to a transaction structure
  411.  @param[in] ms Timeout in msec
  412.  
  413.  @returns Number of bytes received or error
  414.  @retval >0 Number of bytes received
  415.  @retval 0 Timeout
  416.  @retval -1 Error
  417.  */
  418. static int coap_server_trans_dtls_pull_timeout_func(gnutls_transport_ptr_t data, unsigned ms)
  419. {
  420.         coap_server_trans_t *trans = NULL;
  421.         struct sockaddr_in6 client_sin = {0};
  422.         coap_server_t *server = NULL;
  423.         socklen_t client_sin_len = 0;
  424.         ssize_t num = 0;
  425.         char buf[COAP_SERVER_DTLS_MTU] = {0};
  426.         int ret = 0;
  427.         trans = (coap_server_trans_t *)data;
  428.         server = trans->server;
  429.         ret = coap_server_trans_dtls_listen_timeout(trans, ms);
  430.         if (ret == 0)
  431.         {
  432.                 return 0; /* timeout */
  433.         }
  434.         if (ret < 0)
  435.         {
  436.                 return -1;
  437.         }
  438.         client_sin_len = sizeof(client_sin);
  439.         num = recvfrom(server->sd, buf, sizeof(buf), MSG_PEEK, (struct sockaddr *)&client_sin, &client_sin_len); /* peek data */
  440.         if (num == -1)
  441.         {
  442.                 return -1;
  443.         }
  444.         if ((client_sin_len != trans->client_sin_len)
  445.                         || (memcmp(&client_sin, &trans->client_sin, trans->client_sin_len) != 0))
  446.         {
  447.                 gnutls_transport_set_errno(trans->session, EAGAIN);
  448.                 return -1;
  449.         }
  450.         return num; /* success */
  451. }
  452. /*
  453.  @brief Send data to the client
  454.  
  455.  This is a call-back function that the
  456.  GnuTLS library uses to send data.
  457.  
  458.  @param[in] data Pointer to a transaction structure
  459.  @param[in] buf Pointer to a buffer
  460.  @param[in] len Length of the buffer
  461.  
  462.  @returns Number of bytes sent or error
  463.  @retval >0 Number of bytes sent
  464.  @retval -1 Error
  465.  */
  466. static ssize_t coap_server_trans_dtls_push_func(gnutls_transport_ptr_t data, const void *buf, size_t len)
  467. {
  468.         coap_server_trans_t *trans = NULL;
  469.         coap_server_t *server = NULL;
  470.         trans = (coap_server_trans_t *)data;
  471.         server = trans->server;
  472.         return sendto(server->sd, buf, len, 0, (struct sockaddr *)&trans->client_sin, trans->client_sin_len);
  473. }
  474. /*
  475.  @brief Perform a DTLS handshake with the client
  476.  
  477.  @param[in,out] trans Pointer to a transaction structure
  478.  
  479.  @returns Operation success
  480.  @retval 0 Success
  481.  @retval <0 Error
  482.  */
  483. static int coap_server_trans_dtls_handshake(coap_server_trans_t *trans)
  484. {
  485.         int ret = 0;
  486.         int i = 0;
  487.         for (i = 0; i < COAP_SERVER_DTLS_TOTAL_TIMEOUT / COAP_SERVER_DTLS_RETRANS_TIMEOUT; i++)
  488.         {
  489.                 ret = gnutls_handshake(trans->session);
  490.                 if (ret == GNUTLS_E_SUCCESS)
  491.                 {
  492.                         return 0; /* success */
  493.                 }
  494.                 if (ret != GNUTLS_E_AGAIN)
  495.                 {
  496.                         return -1;
  497.                 }
  498.                 ret = coap_server_trans_dtls_listen_timeout(trans, COAP_SERVER_DTLS_RETRANS_TIMEOUT);
  499.                 if (ret < 0)
  500.                 {
  501.                         return ret;
  502.                 }
  503.         }
  504.         return -1;
  505. }
  506. /*
  507.  @brief Initialise the DTLS members of a transaction structure
  508.  
  509.  Perform a DTLS handshake with the client.
  510.  
  511.  @param[out] trans Pointer to a transaction structure
  512.  
  513.  @returns Operation status
  514.  @retval 0 Success
  515.  @retval -1 Error
  516.  */
  517. static int coap_server_trans_dtls_create(coap_server_trans_t *trans)
  518. {
  519.         coap_server_t *server = NULL;
  520.         int ret = 0;
  521.         server = trans->server;
  522.         ret = gnutls_init(&trans->session, GNUTLS_SERVER | GNUTLS_DATAGRAM | GNUTLS_NONBLOCK);
  523.         if (ret != GNUTLS_E_SUCCESS)
  524.         {
  525.                 return -1;
  526.         }
  527.         ret = gnutls_credentials_set(trans->session, GNUTLS_CRD_CERTIFICATE, server->cred);
  528.         if (ret != GNUTLS_E_SUCCESS)
  529.         {
  530.                 gnutls_deinit(trans->session);
  531.                 return -1;
  532.         }
  533.         ret = gnutls_priority_set(trans->session, server->priority);
  534.         if (ret != GNUTLS_E_SUCCESS)
  535.         {
  536.                 gnutls_deinit(trans->session);
  537.                 return -1;
  538.         }
  539.         gnutls_transport_set_ptr(trans->session, trans);
  540.         gnutls_transport_set_pull_function(trans->session, coap_server_trans_dtls_pull_func);
  541.         gnutls_transport_set_pull_timeout_function(trans->session, coap_server_trans_dtls_pull_timeout_func);
  542.         gnutls_transport_set_push_function(trans->session, coap_server_trans_dtls_push_func);
  543.         gnutls_dtls_set_mtu(trans->session, COAP_SERVER_DTLS_MTU);
  544.         gnutls_dtls_set_timeouts(trans->session, COAP_SERVER_DTLS_RETRANS_TIMEOUT, COAP_SERVER_DTLS_TOTAL_TIMEOUT);
  545.         ret = coap_server_trans_dtls_handshake(trans);
  546.         if (ret < 0)
  547.         {
  548.                 gnutls_deinit(trans->session);
  549.                 return -1;
  550.         }
  551.         return 0;
  552. }
  553. /*
  554.  @brief Deinitialise the DTLS members of a transaction structure
  555.  
  556.  @param[in,out] trans Pointer to a transaction structure
  557.  */
  558. static void coap_server_trans_dtls_destroy(coap_server_trans_t *trans)
  559. {
  560.         gnutls_deinit(trans->session);
  561. }
  562. #endif /* COAP_DTLS_EN */
  563. /**************************************************************************************************
  564.  * coap_server_trans  *
  565.  **************************************************************************************************/
  566. /*
  567.  @brief Deinitialise a transaction structure
  568.  
  569.  @param[in,out] trans Pointer to a transaction structure
  570.  */
  571. static void coap_server_trans_destroy(coap_server_trans_t *trans)
  572. {
  573.         coap_log_debug("Destroyed transaction for address %s and port %u", trans->client_addr, ntohs(trans->client_sin.sin6_port));
  574. #ifdef COAP_DTLS_EN
  575.         coap_server_trans_dtls_destroy(trans);
  576. #endif
  577.         coap_msg_destroy(&trans->resp);
  578.         coap_msg_destroy(&trans->req);
  579.         close(trans->timer_fd);
  580.         memset(trans, 0, sizeof(coap_server_trans_t));
  581. }
  582. /*
  583.  @brief Mark the last time the transaction structure was used
  584.  
  585.  @param[out] trans Pointer to a transaction structure
  586.  */
  587. static void coap_server_trans_touch(coap_server_trans_t *trans)
  588. {
  589.         trans->last_use = time(NULL);
  590. }
  591. /*
  592.  @brief Compare a received message with the request part of a transaction structure
  593.  
  594.  @param[in] trans Pointer to a trasaction structure
  595.  @param[in] msg Pointer to a message structure
  596.  
  597.  @returns Comparison value
  598.  @retval 0 The message does not match the transaction
  599.  @retval 1 The message matches the transaction
  600.  */
  601. static int coap_server_trans_match_req(coap_server_trans_t *trans, coap_msg_t *msg)
  602. {
  603.         return ((coap_msg_get_ver(&trans->req) != 0)
  604.                         && (coap_msg_get_msg_id(&trans->req) == coap_msg_get_msg_id(msg)));
  605. }
  606. /*
  607.  @brief Compare a recevied message with the response part of a transaction structure
  608.  
  609.  @param[in] trans Pointer to a trasaction structure
  610.  @param[in] msg Pointer to a message structure
  611.  
  612.  @returns Comparison value
  613.  @retval 0 The message does not match the transaction
  614.  @retval 1 The message matches the transaction
  615.  */
  616. static int coap_server_trans_match_resp(coap_server_trans_t *trans, coap_msg_t *msg)
  617. {
  618.         return ((coap_msg_get_ver(&trans->resp) != 0)
  619.                         && (coap_msg_get_msg_id(&trans->resp) == coap_msg_get_msg_id(msg)));
  620. }
  621. /*
  622.  @brief Clear the request message in a transaction structure
  623.  
  624.  @param[in,out] trans Pointer to a transaction structure
  625.  */
  626. static void coap_server_trans_clear_req(coap_server_trans_t *trans)
  627. {
  628.         coap_msg_destroy(&trans->req);
  629. }
  630. /*
  631.  @brief Clear the response message in a transaction structure
  632.  
  633.  @param[in,out] trans Pointer to a transaction structure
  634.  */
  635. static void coap_server_trans_clear_resp(coap_server_trans_t *trans)
  636. {
  637.         coap_msg_destroy(&trans->resp);
  638. }
  639. /*
  640.  @brief Aşağıda bulunan fonksiyonlar kullanılmadığı için şimdilik çıkarılmıştır
  641.  */
  642. #if 0
  643. /*
  644.  @brief Set the request message in a transaction structure
  645.  
  646.  @param[in,out] trans Pointer to a transaction structure
  647.  @param[in] msg Pointer to a message structure
  648.  
  649.  @returns Operation status
  650.  @retval 0 Success
  651.  @retval <0 Error
  652.  */
  653. static int coap_server_trans_set_req(coap_server_trans_t *trans, coap_msg_t *msg)
  654. {
  655.         coap_msg_reset(&trans->req);
  656.         return coap_msg_copy(&trans->req, msg);
  657. }
  658. /*
  659.  @brief Set the response message in a transaction structure
  660.  
  661.  @param[in,out] trans Pointer to a transaction structure
  662.  @param[in] msg Pointer to a message structure
  663.  
  664.  @returns Operation status
  665.  @retval 0 Success
  666.  @retval <0 Error
  667.  */
  668. static int coap_server_trans_set_resp(coap_server_trans_t *trans, coap_msg_t *msg)
  669. {
  670.         coap_msg_reset(&trans->resp);
  671.         return coap_msg_copy(&trans->resp, msg);
  672. }
  673. /*
  674.  @brief Initialise the acknowledgement timer in a transaction structure
  675.  
  676.  The timer is initialised to a random duration between:
  677.  
  678.  ACK_TIMEOUT and (ACK_TIMEOUT * ACK_RANDOM_FACTOR)
  679.  where:
  680.  ACK_TIMEOUT = 2
  681.  ACK_RANDOM_FACTOR = 1.5
  682.  
  683.  @param[out] trans Pointer to a transaction structure
  684.  */
  685. static void coap_server_trans_init_ack_timeout(coap_server_trans_t *trans)
  686. {
  687.         if (!rand_init)
  688.         {
  689.                 srand(time(NULL));
  690.                 rand_init = 1;
  691.         }
  692.         trans->timeout.tv_sec = COAP_SERVER_ACK_TIMEOUT_SEC;
  693.         trans->timeout.tv_nsec = (rand() % 1000) * 1000000;
  694.         coap_log_debug("Acknowledgement timeout initialised to: %lu sec, %lu nsec", trans->timeout.tv_sec, trans->timeout.tv_nsec);
  695. }
  696. #endif
  697. /*
  698.  @brief Double the value of the timer in a transaction structure
  699.  
  700.  @param[in,out] trans Pointer to a trans structure
  701.  */
  702. static void coap_server_trans_double_timeout(coap_server_trans_t *trans)
  703. {
  704.         unsigned msec = 2 * ((trans->timeout.tv_sec * 1000)
  705.                         + (trans->timeout.tv_nsec / 1000000));
  706.         trans->timeout.tv_sec = msec / 1000;
  707.         trans->timeout.tv_nsec = (msec % 1000) * 1000000;
  708.         coap_log_debug("Timeout doubled to: %lu sec, %lu nsec", trans->timeout.tv_sec, trans->timeout.tv_nsec);
  709. }
  710. /*
  711.  @brief Start the timer in a transaction structure
  712.  
  713.  @param[in,out] trans Pointer to a transaction structure
  714.  
  715.  @returns Operation status
  716.  @retval 0 Success
  717.  @retval <0 Error
  718.  */
  719. static int coap_server_trans_start_timer(coap_server_trans_t *trans)
  720. {
  721.         struct itimerspec its = {{0}};
  722.         int ret = 0;
  723.         its.it_value = trans->timeout;
  724.         ret = timerfd_settime(trans->timer_fd, 0, &its, NULL);
  725.         if (ret == -1)
  726.         {
  727.                 return -errno;
  728.         }
  729.         return 0;
  730. }
  731. /*
  732.  @brief Stop the timer in a transaction structure
  733.  
  734.  @param[out] trans Pointer to a transaction structure
  735.  
  736.  @returns Operation status
  737.  @retval 0 Success
  738.  @retval <0 Error
  739.  */
  740. static int coap_server_trans_stop_timer(coap_server_trans_t *trans)
  741. {
  742.         struct itimerspec its = {{0}};
  743.         int ret = 0;
  744.         ret = timerfd_settime(trans->timer_fd, 0, &its, NULL);
  745.         if (ret == -1)
  746.         {
  747.                 return -errno;
  748.         }
  749.         return 0;
  750. }
  751. /*
  752.  @brief Aşağıda bulunan fonksiyonlar kullanılmadığı için şimdilik çıkarılmıştır
  753.  */
  754. #if 0
  755. /*
  756.  @brief Initialise and start the acknowledgement timer in a transaction structure
  757.  
  758.  @param[out] trans Pointer to a trans structure
  759.  
  760.  @returns Operation status
  761.  @retval 0 Success
  762.  @retval <0 Error
  763.  */
  764. static int coap_server_trans_start_ack_timer(coap_server_trans_t *trans)
  765. {
  766.         trans->num_retrans = 0;
  767.         coap_server_trans_init_ack_timeout(trans);
  768.         return coap_server_trans_start_timer(trans);
  769. }
  770. #endif
  771. /*
  772.  @brief Stop the acknowledgement timer in a transaction structure
  773.  
  774.  @param[out] trans Pointer to a transaction structure
  775.  
  776.  @returns Operation status
  777.  @retval 0 Success
  778.  @retval <0 Error
  779.  */
  780. static int coap_server_trans_stop_ack_timer(coap_server_trans_t *trans)
  781. {
  782.         trans->num_retrans = 0;
  783.         return coap_server_trans_stop_timer(trans);
  784. }
  785. /*
  786.  @brief Update the acknowledgement timer in a transaction structure
  787.  
  788.  Increase and restart the acknowledgement timer in a transaction structure
  789.  and indicate if the maximum number of retransmits has been reached.
  790.  
  791.  @param[in,out] trans Pointer to a trans structure
  792.  
  793.  @returns Operation status
  794.  @retval 0 Success
  795.  @retval <0 Error
  796.  */
  797. static int coap_server_trans_update_ack_timer(coap_server_trans_t *trans)
  798. {
  799.         int ret = 0;
  800.         if (trans->num_retrans >= COAP_SERVER_MAX_RETRANSMIT)
  801.         {
  802.                 return -ETIMEDOUT;
  803.         }
  804.         coap_server_trans_double_timeout(trans);
  805.         ret = coap_server_trans_start_timer(trans);
  806.         if (ret < 0)
  807.         {
  808.                 return ret;
  809.         }
  810.         trans->num_retrans++;
  811.         return 0;
  812. }
  813. /*
  814.  @brief Send a message to the client
  815.  
  816.  @param[in,out] trans Pointer to a transaction structure
  817.  @param[in] msg Pointer to a message structure
  818.  
  819.  @returns Number of bytes sent or error code
  820.  @retval >0 Number of bytes sent
  821.  @retval <0 Error
  822.  */
  823. static ssize_t coap_server_trans_send(coap_server_trans_t *trans, coap_msg_t *msg)
  824. {
  825.         if(trans == NULL)
  826.                 ERR("Response mesajının Transaction structı bulunamadı, response gönderilemiyor");
  827.         if(msg == NULL)
  828.                 ERR("Response mesajı içi NULL");
  829. #ifndef COAP_DTLS_EN
  830.         coap_server_t *server = NULL;
  831. #endif
  832.         ssize_t num = 0;
  833.         char buf[COAP_MSG_MAX_BUF_LEN] = {0};
  834.         num = coap_msg_format(msg, buf, sizeof(buf));
  835.         if (num < 0)
  836.         {
  837.                 return num;
  838.         }
  839. #ifdef COAP_DTLS_EN
  840.         num = gnutls_record_send(trans->session, buf, num);
  841.         if (num < 0)
  842.         {
  843.                 if (num == GNUTLS_E_AGAIN)
  844.                 {
  845.                         return -EAGAIN;
  846.                 }
  847.                 return -1;
  848.         }
  849. #else
  850.         server = trans->server;
  851.         num = sendto(server->sd, buf, num, 0, (struct sockaddr *)&trans->client_sin, trans->client_sin_len);
  852.         if (num == -1)
  853.         {
  854.                 return -errno;
  855.         }
  856. #endif
  857.         coap_server_trans_touch(trans);
  858.         coap_log_debug("Sent to address %s and port %u", trans->client_addr, ntohs(trans->client_sin.sin6_port));
  859.         return num;
  860. }
  861. /*
  862.  @brief Handle a format error in a received message
  863.  
  864.  Special handling for the case where a received
  865.  message could not be parsed due to a format error.
  866.  Extract enough information from the received message
  867.  to form a reset message.
  868.  
  869.  @param[in,out] trans Pointer to a transaction structure
  870.  @param[in] buf Buffer containing the message
  871.  @param[in] len length of the buffer
  872.  */
  873. static void coap_server_trans_handle_format_error(coap_server_trans_t *trans, char *buf, unsigned len)
  874. {
  875.         coap_msg_t msg = {0};
  876.         unsigned msg_id = 0;
  877.         unsigned type = 0;
  878.         int ret = 0;
  879.         /* extract enough information to form a reset message */
  880.         ret = coap_msg_parse_type_msg_id(buf, len, &type, &msg_id);
  881.         if ((ret == 0) && (type == COAP_MSG_CON))
  882.         {
  883.                 coap_msg_create(&msg);
  884.                 ret = coap_msg_set_type(&msg, COAP_MSG_RST);
  885.                 if (ret < 0)
  886.                 {
  887.                         coap_msg_destroy(&msg);
  888.                         return;
  889.                 }
  890.                 ret = coap_msg_set_msg_id(&msg, msg_id);
  891.                 if (ret < 0)
  892.                 {
  893.                         coap_msg_destroy(&msg);
  894.                         return;
  895.                 }
  896.                 coap_server_trans_send(trans, &msg);
  897.                 coap_msg_destroy(&msg);
  898.         }
  899. }
  900. /*
  901.  @brief Receive a message from the client
  902.  
  903.  @param[in,out] trans Pointer to a transaction structure
  904.  @param[in] msg Pointer to a message structure
  905.  
  906.  @returns Number of bytes received or error code
  907.  @retval >0 Number of bytes received
  908.  @retval <0 Error
  909.  */
  910. static ssize_t coap_server_trans_recv(coap_server_trans_t *trans, coap_msg_t *msg)
  911. {
  912. #ifndef COAP_DTLS_EN
  913.         struct sockaddr_in6 client_sin = {0};
  914.         coap_server_t *server = NULL;
  915.         socklen_t client_sin_len = 0;
  916. #endif
  917.         ssize_t num = 0;
  918.         ssize_t ret = 0;
  919.         char buf[COAP_MSG_MAX_BUF_LEN] = {0};
  920. #ifdef COAP_DTLS_EN
  921.         num = gnutls_record_recv(trans->session, buf, sizeof(buf));
  922.         if (num < 0)
  923.         {
  924.                 if (num == GNUTLS_E_AGAIN)
  925.                 {
  926.                         return -EAGAIN;
  927.                 }
  928.                 return -1;
  929.         }
  930. #else
  931.         server = trans->server;
  932.         client_sin_len = sizeof(client_sin);
  933.         num = recvfrom(server->sd, buf, sizeof(buf), MSG_PEEK, (struct sockaddr *)&client_sin, &client_sin_len);
  934.         if (num == -1)
  935.         {
  936.                 return -errno;
  937.         }
  938.         if ((client_sin_len != trans->client_sin_len)
  939.                         || (memcmp(&client_sin, &trans->client_sin, client_sin_len) != 0))
  940.         {
  941.                 return -EAGAIN;
  942.         }
  943.         num = recvfrom(server->sd, buf, num, 0, (struct sockaddr *)&client_sin, &client_sin_len);
  944.         if (num == -1)
  945.         {
  946.                 return -errno;
  947.         }
  948. #endif
  949.         ret = coap_msg_parse(msg, buf, num);
  950.         if (ret < 0)
  951.         {
  952.                 if (ret == -EBADMSG)
  953.                 {
  954.                         coap_server_trans_handle_format_error(trans, buf, num);
  955.                 }
  956.                 return ret;
  957.         }
  958.         coap_server_trans_touch(trans);
  959.         coap_log_debug("Received from address %s and port %u", trans->client_addr, ntohs(trans->client_sin.sin6_port));
  960.         return num;
  961. }
  962. /*
  963.  @brief Reject a received confirmable message
  964.  
  965.  Send a reset message to the client.
  966.  
  967.  @param[in,out] trans Pointer to a transaction structure
  968.  @param[in] msg Pointer to a message structure
  969.  
  970.  @returns Operation status
  971.  @retval 0 Success
  972.  @retval <0 Error
  973.  */
  974. static int coap_server_trans_reject_con(coap_server_trans_t *trans, coap_msg_t *msg)
  975. {
  976.         coap_msg_t rej = {0};
  977.         ssize_t num = 0;
  978.         int ret = 0;
  979.         coap_log_info("Rejecting confirmable request from address %s and port %u", trans->client_addr, ntohs(trans->client_sin.sin6_port));
  980.         coap_msg_create(&rej);
  981.         ret = coap_msg_set_type(&rej, COAP_MSG_RST);
  982.         if (ret < 0)
  983.         {
  984.                 coap_msg_destroy(&rej);
  985.                 return ret;
  986.         }
  987.         ret = coap_msg_set_msg_id(&rej, coap_msg_get_msg_id(msg));
  988.         if (ret < 0)
  989.         {
  990.                 coap_msg_destroy(&rej);
  991.                 return ret;
  992.         }
  993.         num = coap_server_trans_send(trans, &rej);
  994.         coap_msg_destroy(&rej);
  995.         if (num < 0)
  996.         {
  997.                 return num;
  998.         }
  999.         return 0;
  1000. }
  1001. /*
  1002.  @brief Reject a received non-confirmable message
  1003.  
  1004.  @param[in] trans Pointer to a transaction structure
  1005.  @param[in] msg Pointer to a message structure
  1006.  
  1007.  @returns Operation status
  1008.  @retval 0 Success
  1009.  */
  1010. static int coap_server_trans_reject_non(coap_server_trans_t *trans, coap_msg_t *msg)
  1011. {
  1012.         coap_log_info("Rejecting non-confirmable message from address %s and port %u", trans->client_addr, ntohs(trans->client_sin.sin6_port));
  1013.         return 0;
  1014. }
  1015. /*
  1016.  @brief Reject a received message
  1017.  
  1018.  @param[in,out] trans Pointer to a transaction structure
  1019.  @param[in] msg Pointer to a message structure
  1020.  
  1021.  @returns Operation status
  1022.  @retval 0 Success
  1023.  @retval <0 Error
  1024.  */
  1025. static int coap_server_trans_reject(coap_server_trans_t *trans, coap_msg_t *msg)
  1026. {
  1027.         if (coap_msg_get_type(msg) == COAP_MSG_CON)
  1028.         {
  1029.                 return coap_server_trans_reject_con(trans, msg);
  1030.         }
  1031.         return coap_server_trans_reject_non(trans, msg);
  1032. }
  1033. /*
  1034.  @brief Reject a request message containing a bad option
  1035.  
  1036.  @param[in,out] trans Pointer to a transaction structure
  1037.  @param[in] msg Pointer to a message structure
  1038.  @param[in] op_num Option number of the bad option
  1039.  
  1040.  @returns Operation status
  1041.  @retval 0 Success
  1042.  @retval <0 Error
  1043.  */
  1044. int coap_server_trans_reject_bad_option(coap_server_trans_t *trans, coap_msg_t *msg, unsigned op_num)
  1045. {
  1046.         coap_msg_t rej = {0};
  1047.         char payload[COAP_SERVER_DIAG_PAYLOAD_LEN] = {0};
  1048.         ssize_t num = 0;
  1049.         int ret = 0;
  1050.         if (coap_msg_get_type(msg) == COAP_MSG_NON)
  1051.         {
  1052.                 return coap_server_trans_reject_non(trans, msg);
  1053.         }
  1054.         /* confirmable request containing a bad option */
  1055.         /* send a piggy-backed response containing 4.02 Bad Option */
  1056.         coap_msg_create(&rej);
  1057.         ret = coap_msg_set_type(&rej, COAP_MSG_ACK);
  1058.         if (ret != 0)
  1059.         {
  1060.                 coap_msg_destroy(&rej);
  1061.                 return ret;
  1062.         }
  1063.         ret = coap_msg_set_code(&rej, COAP_MSG_CLIENT_ERR, COAP_MSG_BAD_OPTION);
  1064.         if (ret != 0)
  1065.         {
  1066.                 coap_msg_destroy(&rej);
  1067.                 return ret;
  1068.         }
  1069.         ret = coap_msg_set_msg_id(&rej, coap_msg_get_msg_id(msg));
  1070.         if (ret != 0)
  1071.         {
  1072.                 coap_msg_destroy(&rej);
  1073.                 return ret;
  1074.         }
  1075.         ret = coap_msg_set_token(&rej, coap_msg_get_token(msg), coap_msg_get_token_len(msg));
  1076.         if (ret != 0)
  1077.         {
  1078.                 coap_msg_destroy(&rej);
  1079.                 return ret;
  1080.         }
  1081.         snprintf(payload, sizeof(payload), "Bad option number: %u", op_num);
  1082.         ret = coap_msg_set_payload(&rej, payload, strlen(payload));
  1083.         if (ret != 0)
  1084.         {
  1085.                 coap_msg_destroy(&rej);
  1086.                 return ret;
  1087.         }
  1088.         num = coap_server_trans_send(trans, &rej);
  1089.         if (num < 0)
  1090.         {
  1091.                 coap_msg_destroy(&rej);
  1092.                 return num;
  1093.         }
  1094.         coap_msg_destroy(&rej);
  1095.         return 0;
  1096. }
  1097. /*
  1098.  @brief Send an acknowledgement message to the client
  1099.  
  1100.  @param[in,out] trans Pointer to a transaction structure
  1101.  @param[in] msg Pointer to a message structure
  1102.  
  1103.  @returns Operation status
  1104.  @retval 0 Success
  1105.  @retval <0 Error
  1106.  */
  1107. static int coap_server_trans_send_ack(coap_server_trans_t *trans, coap_msg_t *msg)
  1108. {
  1109.         coap_msg_t ack = {0};
  1110.         ssize_t num = 0;
  1111.         int ret = 0;
  1112.         coap_log_info("Acknowledging confirmable message from address %s and port %u", trans->client_addr, ntohs(trans->client_sin.sin6_port));
  1113.         coap_msg_create(&ack);
  1114.         ret = coap_msg_set_type(&ack, COAP_MSG_ACK);
  1115.         if (ret < 0)
  1116.         {
  1117.                 coap_msg_destroy(&ack);
  1118.                 return ret;
  1119.         }
  1120.         ret = coap_msg_set_msg_id(&ack, coap_msg_get_msg_id(msg));
  1121.         if (ret < 0)
  1122.         {
  1123.                 coap_msg_destroy(&ack);
  1124.                 return ret;
  1125.         }
  1126.         num = coap_server_trans_send(trans, &ack);
  1127.         coap_msg_destroy(&ack);
  1128.         if (num < 0)
  1129.         {
  1130.                 return num;
  1131.         }
  1132.         return 0;
  1133. }
  1134. /*
  1135.  @brief Handle an acknowledgement timeout
  1136.  
  1137.  Update the acknowledgement timer in the transaction structure
  1138.  and if the maximum number of retransmits has not been reached
  1139.  then retransmit the last response to the client.
  1140.  
  1141.  @param[in,out] trans Pointer to a transaction structure
  1142.  
  1143.  @returns Operation status
  1144.  @retval 0 Success
  1145.  @retval <0 Error
  1146.  */
  1147. static int coap_server_trans_handle_ack_timeout(coap_server_trans_t *trans)
  1148. {
  1149.         ssize_t num = 0;
  1150.         int ret = 0;
  1151.         coap_log_debug("Transaction expired for address %s and port %u", trans->client_addr, ntohs(trans->client_sin.sin6_port));
  1152.         ret = coap_server_trans_update_ack_timer(trans);
  1153.         if (ret == 0)
  1154.         {
  1155.                 coap_log_debug("Retransmitting to address %s and port %u", trans->client_addr, ntohs(trans->client_sin.sin6_port));
  1156.                 num = coap_server_trans_send(trans, &trans->resp);
  1157.                 if (num < 0)
  1158.                 {
  1159.                         return num;
  1160.                 }
  1161.         }
  1162.         else if (ret == -ETIMEDOUT)
  1163.         {
  1164.                 coap_log_debug("Stopped retransmitting to address %s and port %u", trans->client_addr, ntohs(trans->client_sin.sin6_port));
  1165.                 coap_log_info("No acknowledgement received from address %s and port %u", trans->client_addr, ntohs(trans->client_sin.sin6_port));
  1166.                 coap_server_trans_destroy(trans);
  1167.                 ret = 0;
  1168.         }
  1169.         return ret;
  1170. }
  1171. /*
  1172.  @brief Initialise a transaction structure
  1173.  
  1174.  @param[out] trans Pointer to a transaction structure
  1175.  @param[in] server Pointer to a server structure
  1176.  @param[in] client_sin Pointer to a struct sockaddr_in6
  1177.  @param[in] client_sin_len Length of the struct sockaddr_in6
  1178.  
  1179.  @returns Operation status
  1180.  @retval 0 Success
  1181.  @retval <0 Error
  1182.  */
  1183. static int coap_server_trans_create(coap_server_trans_t *trans, coap_server_t *server, struct sockaddr_in6 *client_sin, socklen_t client_sin_len)
  1184. {
  1185.         const char *p = NULL;
  1186. #ifdef COAP_DTLS_EN
  1187.         int ret = 0;
  1188. #endif
  1189.         memset(trans, 0, sizeof(coap_server_trans_t));
  1190.         trans->active = 1;
  1191.         coap_server_trans_touch(trans);
  1192.         trans->timer_fd = timerfd_create(CLOCK_MONOTONIC, TFD_NONBLOCK);
  1193.         if (trans->timer_fd == -1)
  1194.         {
  1195.                 memset(trans, 0, sizeof(coap_server_trans_t));
  1196.                 return -errno;
  1197.         }
  1198.         memcpy(&trans->client_sin, client_sin, client_sin_len);
  1199.         trans->client_sin_len = client_sin_len;
  1200.         p = inet_ntop(AF_INET6, &client_sin->sin6_addr, trans->client_addr, sizeof(trans->client_addr));
  1201.         if (p == NULL)
  1202.         {
  1203.                 close(trans->timer_fd);
  1204.                 memset(trans, 0, sizeof(coap_server_trans_t));
  1205.                 return -errno;
  1206.         }
  1207.         coap_msg_create(&trans->req);
  1208.         coap_msg_create(&trans->resp);
  1209.         trans->server = server;
  1210. #ifdef COAP_DTLS_EN
  1211.         ret = coap_server_trans_dtls_create(trans);
  1212.         if (ret < 0)
  1213.         {
  1214.                 coap_msg_destroy(&trans->resp);
  1215.                 coap_msg_destroy(&trans->req);
  1216.                 close(trans->timer_fd);
  1217.                 memset(trans, 0, sizeof(coap_server_trans_t));
  1218.                 return ret;
  1219.         }
  1220. #endif
  1221.         coap_log_debug("Created transaction for address %s and port %u", trans->client_addr, ntohs(trans->client_sin.sin6_port));
  1222.         return 0;
  1223. }
  1224. #ifdef COAP_DTLS_EN
  1225. /**********************************************************************************************
  1226.  *  coap_server_dtls  *
  1227.  **********************************************************************************************/
  1228. /*
  1229.  @brief Initialise the DTLS members of a server structure
  1230.  
  1231.  @param[out] server Pointer to a server structure
  1232.  @param[in] key_file_name String containing the DTLS key file name
  1233.  @param[in] cert_file_name String containing the DTLS certificate file name
  1234.  @param[in] trust_file_name String containing the DTLS trust file name
  1235.  @param[in] crl_file_name String containing the DTLS certificate revocation list file name
  1236.  
  1237.  @returns Operation status
  1238.  @retval 0 Success
  1239.  @retval -1 Error
  1240.  */
  1241. static int coap_server_dtls_create(coap_server_t *server,
  1242.                 const char *key_file_name,
  1243.                 const char *cert_file_name,
  1244.                 const char *trust_file_name,
  1245.                 const char *crl_file_name)
  1246. {
  1247.         int ret = 0;
  1248.         ret = gnutls_global_init();
  1249.         if (ret != GNUTLS_E_SUCCESS)
  1250.         {
  1251.                 return -1;
  1252.         }
  1253.         ret = gnutls_certificate_allocate_credentials(&server->cred);
  1254.         if (ret != GNUTLS_E_SUCCESS)
  1255.         {
  1256.                 gnutls_global_deinit();
  1257.                 return -1;
  1258.         }
  1259.         if ((trust_file_name != NULL) && (strlen(trust_file_name) != 0))
  1260.         {
  1261.                 ret = gnutls_certificate_set_x509_trust_file(server->cred, trust_file_name, GNUTLS_X509_FMT_PEM);
  1262.                 if (ret == 0)
  1263.                 {
  1264.                         gnutls_certificate_free_credentials(server->cred);
  1265.                         gnutls_global_deinit();
  1266.                         return -1;
  1267.                 }
  1268.         }
  1269.         if ((crl_file_name != NULL) && (strlen(crl_file_name) != 0))
  1270.         {
  1271.                 ret = gnutls_certificate_set_x509_crl_file(server->cred, crl_file_name, GNUTLS_X509_FMT_PEM);
  1272.                 if (ret < 0)
  1273.                 {
  1274.                         gnutls_certificate_free_credentials(server->cred);
  1275.                         gnutls_global_deinit();
  1276.                         return -1;
  1277.                 }
  1278.         }
  1279.         ret = gnutls_certificate_set_x509_key_file(server->cred, cert_file_name, key_file_name, GNUTLS_X509_FMT_PEM);
  1280.         if (ret != GNUTLS_E_SUCCESS)
  1281.         {
  1282.                 gnutls_certificate_free_credentials(server->cred);
  1283.                 gnutls_global_deinit();
  1284.                 return -1;
  1285.         }
  1286.         ret = gnutls_dh_params_init(&server->dh_params);
  1287.         if (ret != GNUTLS_E_SUCCESS)
  1288.         {
  1289.                 gnutls_certificate_free_credentials(server->cred);
  1290.                 gnutls_global_deinit();
  1291.                 return -1;
  1292.         }
  1293.         ret = gnutls_dh_params_generate2(server->dh_params, COAP_SERVER_DTLS_NUM_DH_BITS);
  1294.         if (ret != GNUTLS_E_SUCCESS)
  1295.         {
  1296.                 gnutls_dh_params_deinit(server->dh_params);
  1297.                 gnutls_certificate_free_credentials(server->cred);
  1298.                 gnutls_global_deinit();
  1299.                 return -1;
  1300.         }
  1301.         gnutls_certificate_set_dh_params(server->cred, server->dh_params);
  1302.         ret = gnutls_priority_init(&server->priority, COAP_SERVER_DTLS_PRIORITIES, NULL);
  1303.         if (ret != GNUTLS_E_SUCCESS)
  1304.         {
  1305.                 gnutls_dh_params_deinit(server->dh_params);
  1306.                 gnutls_certificate_free_credentials(server->cred);
  1307.                 gnutls_global_deinit();
  1308.                 return -1;
  1309.         }
  1310.         return 0;
  1311. }
  1312. /*
  1313.  @brief Deinitialise the DTLS members of a server structure
  1314.  
  1315.  @param[in,out] trans Pointer to a server structure
  1316.  */
  1317. static void coap_server_dtls_destroy(coap_server_t *server)
  1318. {
  1319.         gnutls_priority_deinit(server->priority);
  1320.         gnutls_certificate_free_credentials(server->cred);
  1321.         gnutls_dh_params_deinit(server->dh_params);
  1322.         gnutls_global_deinit();
  1323. }
  1324. #endif /* COAP_DTLS_EN */
  1325. /*********************************************************************************************
  1326.  * coap_server  *
  1327.  *********************************************************************************************/
  1328. #ifdef COAP_DTLS_EN
  1329. int coap_server_create(coap_server_t *server,
  1330.                 int (* handle)(coap_server_t *, coap_msg_t *, coap_msg_t *),
  1331.                 const char *host,
  1332.                 unsigned port,
  1333.                 const char *key_file_name,
  1334.                 const char *cert_file_name,
  1335.                 const char *trust_file_name,
  1336.                 const char *crl_file_name)
  1337. #else
  1338. int coap_server_create(coap_server_t *server,
  1339.                 int (* handle)(coap_server_t *, coap_msg_t *, coap_msg_t *),
  1340.                 const char *host,
  1341.                 unsigned port)
  1342. #endif
  1343. {
  1344.         struct sockaddr_in6 server_sin = {0};
  1345.         unsigned char msg_id[2] = {0};
  1346.         const char *p = NULL;
  1347.         socklen_t server_sin_len = 0;
  1348.         char server_addr[COAP_SERVER_ADDR_BUF_LEN] = {0};
  1349.         int opt_val = 0;
  1350.         int flags = 0;
  1351.         int ret = 0;
  1352.  
  1353.         if ((server == NULL) || (host == NULL))
  1354.         {
  1355.                 return -EINVAL;
  1356.         }
  1357.         memset(server, 0, sizeof(coap_server_t));
  1358.         server->sd = socket(PF_INET6, SOCK_DGRAM, 0);
  1359.         if (server->sd == -1)
  1360.         {
  1361.                 memset(server, 0, sizeof(coap_server_t));
  1362.                 return -errno;
  1363.         }
  1364.         flags = fcntl(server->sd, F_GETFL, 0);
  1365.         if (flags == -1)
  1366.         {
  1367.                 close(server->sd);
  1368.                 memset(server, 0, sizeof(coap_server_t));
  1369.                 return -errno;
  1370.         }
  1371.         ret = fcntl(server->sd, F_SETFL, flags | O_NONBLOCK);
  1372.         if (ret == -1)
  1373.         {
  1374.                 close(server->sd);
  1375.                 memset(server, 0, sizeof(coap_server_t));
  1376.                 return -errno;
  1377.         }
  1378.         opt_val = 1;
  1379.         ret = setsockopt(server->sd, SOL_SOCKET, SO_REUSEADDR, &opt_val, (socklen_t)sizeof(opt_val));
  1380.         if (ret == -1)
  1381.         {
  1382.                 close(server->sd);
  1383.                 memset(server, 0, sizeof(coap_server_t));
  1384.                 return -errno;
  1385.         }
  1386.         server_sin.sin6_family = AF_INET6;
  1387.         server_sin.sin6_port = htons(port);
  1388.         ret = inet_pton(AF_INET6, host, &server_sin.sin6_addr);
  1389.         if (ret == 0)
  1390.         {
  1391.                 close(server->sd);
  1392.                 memset(server, 0, sizeof(coap_server_t));
  1393.                 return -EINVAL;
  1394.         }
  1395.         else if (ret == -1)
  1396.         {
  1397.                 close(server->sd);
  1398.                 memset(server, 0, sizeof(coap_server_t));
  1399.                 return -errno;
  1400.         }
  1401.         /*
  1402.          * @brief accept connections from any ipv6 address
  1403.          * */
  1404.         server_sin.sin6_addr = in6addr_any;
  1405.         server_sin_len = sizeof(server_sin);
  1406.         ret = bind(server->sd, (struct sockaddr *)&server_sin, server_sin_len);
  1407.         if (ret == -1)
  1408.         {
  1409.                 close(server->sd);
  1410.                 memset(server, 0, sizeof(coap_server_t));
  1411.                 return -errno;
  1412.         }
  1413.         coap_msg_gen_rand_str((char *)msg_id, sizeof(msg_id));
  1414.         server->msg_id = (((unsigned)msg_id[1]) << 8) | (unsigned)msg_id[0];
  1415.         coap_server_path_list_create(&server->sep_list);
  1416.         server->handle = handle;
  1417.         p = inet_ntop(AF_INET6, &server_sin.sin6_addr, server_addr, sizeof(server_addr));
  1418.         if (p == NULL)
  1419.         {
  1420.                 coap_server_path_list_destroy(&server->sep_list);
  1421.                 close(server->sd);
  1422.                 memset(server, 0, sizeof(coap_server_t));
  1423.                 return -errno;
  1424.         }
  1425. #ifdef COAP_DTLS_EN
  1426.         ret = coap_server_dtls_create(server, key_file_name, cert_file_name, trust_file_name, crl_file_name);
  1427.         if (ret < 0)
  1428.         {
  1429.                 coap_server_path_list_destroy(&server->sep_list);
  1430.                 close(server->sd);
  1431.                 memset(server, 0, sizeof(coap_server_t));
  1432.                 return ret;
  1433.         }
  1434. #endif
  1435.         coap_log_notice("Listening on address %s and port %d", server_addr, ntohs(server_sin.sin6_port));
  1436.         return 0;
  1437. }
  1438. /*
  1439.  @brief Server destroy and close the connection
  1440.  */
  1441. void coap_server_destroy(coap_server_t *server)
  1442. {
  1443.         coap_server_trans_t *trans = NULL;
  1444.         unsigned i = 0;
  1445.         for (i = 0; i < COAP_SERVER_NUM_TRANS; i++)
  1446.         {
  1447.                 trans = &server->trans[i];
  1448.                 if (trans->active)
  1449.                 {
  1450.                         coap_server_trans_destroy(trans);
  1451.                 }
  1452.         }
  1453. #ifdef COAP_DTLS_EN
  1454.         coap_server_dtls_destroy(server);
  1455. #endif
  1456.         coap_server_path_list_destroy(&server->sep_list);
  1457.         close(server->sd);
  1458.         memset(server, 0, sizeof(coap_server_t));
  1459. }
  1460. /*
  1461.  @brief Take random message ID
  1462.  
  1463.  @param[in] server Pointer to a server structure
  1464.  
  1465.  @returns Random massage ID
  1466.  */
  1467. unsigned coap_server_get_next_msg_id(coap_server_t *server)
  1468. {
  1469.         unsigned char msg_id[2] = {0};
  1470.         server->msg_id++;
  1471.         while (server->msg_id > COAP_MSG_MAX_MSG_ID)
  1472.         {
  1473.                 coap_msg_gen_rand_str((char *)msg_id, sizeof(msg_id));
  1474.                 server->msg_id = (((unsigned)msg_id[1]) << 8) | (unsigned)msg_id[0];
  1475.         }
  1476.         return server->msg_id;
  1477. }
  1478. /*
  1479.  @brief Check that all of the options in a message are acceptable
  1480.  
  1481.  For a proxy, options are acceptable if they are safe to forward or recognized or both.
  1482.  For a server, options are acceptable if they are elective or recognized or both.
  1483.  
  1484.  @param[in] msg Pointer to message structure
  1485.  
  1486.  @returns Operation status or bad option number
  1487.  @retval 0 Success
  1488.  @retval >0 Bad option number
  1489.  */
  1490. static unsigned coap_server_check_options(coap_msg_t *msg)
  1491. {
  1492. #ifdef COAP_PROXY
  1493.         return coap_msg_check_unsafe_ops(msg);
  1494. #else /* !COAP_PROXY */
  1495.         return coap_msg_check_critical_ops(msg);
  1496. #endif /* COAP_PROXY */
  1497. }
  1498. /*
  1499.  @brief Search for a transaction structure in a server structure that matches an endpoint
  1500.  
  1501.  @param[in] server Pointer to a server structure
  1502.  @param[in] client_sin Pointer to a struct sockaddr_in6
  1503.  @param[in] client_sin_len Length of the struct sockaddr_in6
  1504.  
  1505.  @returns Pointer to a transaction structure
  1506.  @retval NULL No matching transaction structure found
  1507.  */
  1508. static coap_server_trans_t *coap_server_find_trans(coap_server_t *server, struct sockaddr_in6 *client_sin, socklen_t client_sin_len)
  1509. {
  1510.         coap_server_trans_t *trans = NULL;
  1511.         unsigned i = 0;
  1512.         for (i = 0; i < COAP_SERVER_NUM_TRANS; i++)
  1513.         {
  1514.                 trans = &server->trans[i];
  1515.                 if ((trans->active)
  1516.                                 && (trans->client_sin_len == client_sin_len)
  1517.                                 && (memcmp(&trans->client_sin, client_sin, client_sin_len) == 0))
  1518.                 {
  1519.                         coap_log_debug("Found existing transaction at index %u", i);
  1520.                         return trans;
  1521.                 }
  1522.         }
  1523.         return NULL;
  1524. }
  1525. /*
  1526.  @brief Search for an empty transaction structure in a server structure
  1527.  
  1528.  @param[in] server Pointer to a server structure
  1529.  
  1530.  @returns Pointer to a transaction structure
  1531.  @retval NULL No empty transaction structures available
  1532.  */
  1533. static coap_server_trans_t *coap_server_find_empty_trans(coap_server_t *server)
  1534. {
  1535.         coap_server_trans_t *trans = NULL;
  1536.         unsigned i = 0;
  1537.         for (i = 0; i < COAP_SERVER_NUM_TRANS; i++)
  1538.         {
  1539.                 trans = &server->trans[i];
  1540.                 if (!trans->active)
  1541.                 {
  1542.                         coap_log_debug("Found empty transaction at index %u", i);
  1543.                         return trans;
  1544.                 }
  1545.         }
  1546.         return NULL;
  1547. }
  1548. /*
  1549.  @brief Search for the oldest transaction structure in a server structure
  1550.  
  1551.  Search for the transaction structure in a server structure that was
  1552.  used least recently.
  1553.  
  1554.  @param[in] server Pointer to a server structure
  1555.  
  1556.  @returns Pointer to a transaction structure
  1557.  */
  1558. static coap_server_trans_t *coap_server_find_oldest_trans(coap_server_t *server)
  1559. {
  1560.         coap_server_trans_t *oldest = NULL;
  1561.         coap_server_trans_t *trans = NULL;
  1562.         unsigned i = 0;
  1563.         unsigned j = 0;
  1564.         time_t min_last_use = 0;
  1565.         for (i = 0; i < COAP_SERVER_NUM_TRANS; i++)
  1566.         {
  1567.                 trans = &server->trans[i];
  1568.                 if (trans->active)
  1569.                 {
  1570.                         if ((min_last_use == 0) || (trans->last_use < min_last_use))
  1571.                         {
  1572.                                 oldest = trans;
  1573.                                 min_last_use = trans->last_use;
  1574.                                 j = i;
  1575.                         }
  1576.                 }
  1577.         }
  1578.         coap_log_debug("Found oldest transaction at index %u", j);
  1579.         return oldest != NULL ? oldest : &server->trans[0];
  1580. }
  1581. int response_func(coap_msg_t *response_msg);
  1582. int coap_server_exchange(coap_server_t *server);
  1583. /*
  1584.  @brief Wait for a message to arrive or an acknowledgement
  1585.  timer in any of the active transactions to expire
  1586.  
  1587.  @param[in,out] server Pointer to a server structure
  1588.  
  1589.  @returns Operation status
  1590.  @retval 0 Success
  1591.  @retval <0 Error
  1592.  */
  1593. static int coap_server_listen(coap_server_t *server)
  1594. {
  1595.         coap_server_trans_t *trans = NULL;
  1596.         unsigned i = 0;
  1597.         fd_set read_fds = {{0}};
  1598.         int max_fd = 0;
  1599.         int ret = 0;
  1600.         int ret_select;
  1601.         unsigned msg_id1 = 0;
  1602.         clock_t start, end;
  1603.         double cpu_time_used;
  1604.         LOG(3, "Coap Server Listening...");
  1605.         while (1)
  1606.         {
  1607.                 start = 0;
  1608.                 end = 0;
  1609.                 start = clock();
  1610.                 FD_ZERO(&read_fds);
  1611.                 FD_SET(server->sd, &read_fds);
  1612.                 FD_SET(linda_fd, &read_fds);
  1613.                 max_fd = MAX_A(linda_fd, server->sd);
  1614.  
  1615.                 for (i = 0; i < COAP_SERVER_NUM_TRANS; i++)
  1616.                 {
  1617.                         trans = &server->trans[i];
  1618.                         if (trans->active)
  1619.                         {
  1620.                                 FD_SET(trans->timer_fd, &read_fds);
  1621.                                 if (trans->timer_fd > max_fd)
  1622.                                 {
  1623.                                         max_fd = trans->timer_fd;
  1624.                                 }
  1625.                         }
  1626.                 }
  1627.                 ret_select = select(max_fd + 1, &read_fds, NULL, NULL, NULL);
  1628.                 if (ret_select == -1)
  1629.                 {
  1630.                         return -errno;
  1631.                 }
  1632.                 if (FD_ISSET(server->sd, &read_fds)){
  1633.                         LOG(3,"Server, dış socket baglantısı aldı");
  1634.                         ret = coap_server_exchange(server);
  1635.                         if (ret < 0)
  1636.                         {
  1637.                                 ERR("coap_server_exchange baslatılamadı");
  1638.                         }
  1639.                         ret_select--;
  1640.                 }
  1641.                 if (FD_ISSET(linda_fd, &read_fds)){
  1642.                         LOG(3,"Lindadan mesaj aldı");
  1643.                         coap_msg_t send_msg = {0};
  1644.                         coap_msg_create(&send_msg);
  1645.                         msg_id1 = coap_server_get_next_msg_id(server);
  1646.  
  1647.                         ret = coap_msg_set_msg_id(&send_msg, msg_id1);
  1648.                         if (ret < 0){
  1649.                                 ERR("Msg ID set edilemedi!");
  1650.                                 return ret;
  1651.                         }
  1652.  
  1653.                         ret=response_func(&send_msg);
  1654.                         if (ret<0){
  1655.                                 ERR("Error Rosponse Message  %s",strerror(ret));
  1656.                         }
  1657.  
  1658.                         ret_select--;
  1659.                         linda_rdy(linda);
  1660.                 }
  1661.                 if (ret_select > 0){
  1662.                         ERR("Okunamayan FD var");
  1663.                         BOCEK;
  1664.                 }
  1665.                 for (i = 0; i < COAP_SERVER_NUM_TRANS; i++){
  1666.                         trans = &server->trans[i];
  1667.                         if ((trans->active) && (FD_ISSET(trans->timer_fd, &read_fds))){
  1668.                                 ret = coap_server_trans_handle_ack_timeout(trans);
  1669.                                 if (ret < 0){
  1670.                                         return ret;
  1671.                                 }
  1672.                         }
  1673.                 }
  1674.                 end = clock();
  1675.                 cpu_time_used = ((double) (end - start)) / CLOCKS_PER_SEC;
  1676.                 INFO("Cpu time used-->%f<--", cpu_time_used);
  1677.         }
  1678.         return 0;
  1679. }
  1680. /*
  1681.  @brief Accept an incoming connection
  1682.  
  1683.  @param[in] server Pointer to a server structure
  1684.  @param[out] client_sin Pointer to an IPv6 socket structure
  1685.  @param[out] client_sin_len Length of the IPv6 socket structure
  1686.  
  1687.  Get the address and port number of the client.
  1688.  Do not read the received data.
  1689.  
  1690.  @returns Number of bytes received or error code
  1691.  @retval 0 Success
  1692.  @retval <0 Error
  1693.  */
  1694. static int coap_server_accept(coap_server_t *server, struct sockaddr_in6 *client_sin, socklen_t *client_sin_len)
  1695. {
  1696.         ssize_t num = 0;
  1697.         char buf[COAP_MSG_MAX_BUF_LEN] = {0};
  1698.         *client_sin_len = sizeof(struct sockaddr_in6);
  1699.         num = recvfrom(server->sd, buf, sizeof(buf), MSG_PEEK, (struct sockaddr *)client_sin, client_sin_len);
  1700.         if (num == -1)
  1701.         {
  1702.                 return -errno;
  1703.         }
  1704.         return 0;
  1705. }
  1706. int coap_server_add_sep_resp_uri_path(coap_server_t *server, const char *str)
  1707. {
  1708.         return coap_server_path_list_add(&server->sep_list, str);
  1709. }
  1710. int request_func(coap_msg_t *request_msg, char **rqi_hash_key){
  1711.         coap_msg_op_t *op = NULL;
  1712.         unsigned num = 0;
  1713.         unsigned len = 0;
  1714.         int index = 0;
  1715.         char *val = NULL;
  1716.         char *temp = NULL;
  1717.         coap_hash_uri_query_t query_num;
  1718.         m2m_requestPrimitive_t *preq_primitive =NULL;
  1719.         preq_primitive = m2m_requestPrimitive_init();
  1720.         if (!preq_primitive){
  1721.                 ERR("Request Primitive struct hatalı init");
  1722.         }
  1723.  
  1724.         if (coap_msg_get_code_class(request_msg) == COAP_MSG_REQ){
  1725.                 LOG(3, "CoAP Rqp mesajı Alındı!");
  1726.                 /*operation*/
  1727.                 index = coap_msg_get_code_detail(request_msg);
  1728.                 switch (index)
  1729.                 {
  1730.                         case COAP_MSG_POST :
  1731.                                 preq_primitive->op = 1;
  1732.                                 LOG(3, "CoAP Rqp mesajı operation numarası -->%d<-- type-->POST",preq_primitive->op);
  1733.                                 break;
  1734.                         case COAP_MSG_GET :
  1735.                                 preq_primitive->op = 2;
  1736.                                 LOG(3, "CoAP Rqp mesajı operation numarası -->%d<-- type-->GET",preq_primitive->op);
  1737.                                 break;
  1738.                         case COAP_MSG_PUT :
  1739.                                 preq_primitive->op = 3;
  1740.                                 LOG(3, "CoAP Rqp mesajı operation numarası -->%d<-- type-->PUT",preq_primitive->op);
  1741.                                 break;
  1742.                         case COAP_MSG_DELETE :
  1743.                                 preq_primitive->op = 4;
  1744.                                 LOG(3, "CoAP Rqp mesajı operation numarası -->%d<-- type-->DELETE",preq_primitive->op);
  1745.                                 break;
  1746.                         default :
  1747.                                 ERR("Undefined operation number -->%d<--",index);
  1748.                                 break;
  1749.                 }
  1750.                 index = 0;
  1751.                 /*Parse all taken request option*/
  1752.                 op = coap_msg_get_first_op(request_msg);
  1753.                 while (op != NULL)
  1754.                 {
  1755.                         num = coap_msg_op_get_num(op);
  1756.                         len = coap_msg_op_get_len(op);
  1757.                         val = coap_msg_op_get_val(op);
  1758.                         switch (num){
  1759.                                 /*Request Uri-Host parameter parse*/
  1760.                                 case COAP_MSG_URI_HOST :
  1761.                                         preq_primitive->uri_host = strndup(val, len);
  1762.                                         LOG(3, "CoAP Rqp mesajı Uri_Host -->%s<--",preq_primitive->uri_host);
  1763.                                         break;
  1764.                                         /*Request Uri-Port parameter parse*/
  1765.                                 case COAP_MSG_URI_PORT :
  1766.                                         preq_primitive->uri_port = strndup(val, len);
  1767.                                         LOG(3, "CoAP Rqp mesajı Uri_Port -->%s<--",preq_primitive->uri_port);
  1768.                                         if( preq_primitive->uri_host != NULL && preq_primitive->uri_port != NULL){
  1769.                                                 sprintf((char *)coap_server_glb.json_poa,"coap://[%s]:%s",preq_primitive->uri_host,preq_primitive->uri_port);
  1770.                                                 preq_primitive->poa = strdup(coap_server_glb.json_poa);
  1771.                                                 LOG(3, "Coap Rqp mesajı Poa M2M struct-->%s<--", preq_primitive->poa);                
  1772.                                         }
  1773.                                         break;
  1774.                                         /*Request To parameter parse*/
  1775.                                 case COAP_MSG_URI_PATH :
  1776.                                         preq_primitive->to = strndup(val, len);
  1777.                                         LOG(3, "CoAP Rqp mesajı TO -->%s<--",preq_primitive->to);
  1778.                                         break;
  1779.                                         /*Content Format parameter parse*/
  1780.                                 case COAP_MSG_CONTENT_FORMAT :
  1781.                                         temp = strndup(val, len);
  1782.                                         preq_primitive->conf = g_hash_table_lookup(hash_coap_conf,temp);
  1783.                                         LOG(3,"Request msg CONF -->%s<--",preq_primitive->conf);
  1784.                                         temp = NULL;
  1785.                                         preq_primitive->pc = m2m_primitiveContent_init();
  1786.                                         break;
  1787.                                         /*Query option search and parse*/
  1788.                                 case COAP_MSG_URI_QUERY :
  1789.                                         for (index = 0; index <= len; index++){
  1790.                                                 if(val[index] == '=')
  1791.                                                         break;
  1792.                                         }
  1793.                                         temp = strndup(val, (index));
  1794.                                         query_num = atoi(g_hash_table_lookup(hash_coap_uri_query,temp));
  1795.                                         temp = NULL;
  1796.                                         switch(query_num){
  1797.                                                 case msg_fc_ty :
  1798.                                                         strRemove(val, "ty=");
  1799.                                                         if (preq_primitive->op == 1){
  1800.                                                                 temp = strndup(val, (len-3));
  1801.                                                                 if (validationCheck(ty,temp) == 1){
  1802.                                                                         preq_primitive->ty = atoi(temp);
  1803.                                                                         LOG(3, "CoAP Rqp mesajı ResourceType -->%d<--",preq_primitive->ty);           
  1804.                                                                 }else{
  1805.                                                                         INFO("Resource Type -->%s<-- is not valid", temp);
  1806.                                                                 }
  1807.                                                         }else {
  1808.                                                                 if (preq_primitive->fc == NULL){
  1809.                                                                         preq_primitive->fc = m2m_filterCriteria_init();
  1810.                                                                 }
  1811.                                                                 temp = strndup(val, (len-3));
  1812.                                                                 if (validationCheck(ty,temp) == 1){
  1813.                                                                         preq_primitive->fc->ty = atoi(temp);
  1814.                                                                         LOG(3, "CoAP Rqp mesajı Filte Criteria ResourceType -->%d<--",preq_primitive->fc->ty);
  1815.                                                                 }else{
  1816.                                                                         INFO("Filter Criteria Resource Type -->%s<-- is not valid", temp);
  1817.                                                                 }          
  1818.                                                         }
  1819.                                                         temp = NULL;
  1820.                                                         break;
  1821.  
  1822.                                                 case msg_rt :
  1823.                                                         preq_primitive->rti = m2m_responseTypeInfo_init();
  1824.                                                         if (!preq_primitive->rti){
  1825.                                                                 ERR("Request Primitive, Response type info struct init hatalı");
  1826.                                                         }
  1827.                                                         strRemove(val, "rt=");
  1828.                                                         temp = strndup(val,(len-3));
  1829.                                                         if (validationCheck(rt,temp) == 1){
  1830.                                                                 preq_primitive->rti->rt = atoi(temp);
  1831.                                                                 LOG(3, "CoAP Rqp mesajı ResponseType -->%d<--",preq_primitive->rti->rt);
  1832.                                                         }else{
  1833.                                                                 INFO("Response Type -->%s<-- not valid", temp);
  1834.                                                         }
  1835.                                                         temp =  NULL;
  1836.                                                         break;
  1837.                                                 case msg_rp :
  1838.                                                         strRemove(val, "rp=");
  1839.                                                         temp = strndup(val,(len-3));
  1840.                                                         preq_primitive->rp = atoi(temp);
  1841.                                                         LOG(3, "CoAP Rqp mesajı ResultPersistence -->%d<--",preq_primitive->rp);
  1842.                                                         temp = NULL;
  1843.                                                         break;
  1844.                                                 case msg_rcn :
  1845.                                                         strRemove(val, "rcn=");
  1846.                                                         temp = strndup(val,(len-4));
  1847.                                                         if (validationCheck(rcn,temp) == 1){
  1848.                                                                 preq_primitive->rcn = atoi(temp);
  1849.                                                                 LOG(3, "CoAP Rqp mesajı ResultContent -->%d<--",preq_primitive->rcn);
  1850.                                                         }else{
  1851.                                                                 INFO("Result Content -->%s<-- not valid", temp);
  1852.                                                         }
  1853.                                                         temp = NULL;
  1854.                                                         break;
  1855.                                                 case msg_da :
  1856.                                                         strRemove(val, "da=");
  1857.                                                         temp = strndup(val,(len-3));
  1858.                                                         if (validationCheck(da,temp) == 1){
  1859.                                                                 if(strcmp(temp, "true") == 0){
  1860.                                                                         preq_primitive->da = 1;
  1861.                                                                 }else if (strcmp(temp, "false") == 0){
  1862.                                                                         preq_primitive->da = 2;
  1863.                                                                 }
  1864.                                                                 LOG(3, "CoAP Rqp mesajı DeliveryAggregation -->%d<--",preq_primitive->da);
  1865.                                                         }else{
  1866.                                                                 INFO("Delivery Aggregation -->%s<-- not valid", temp);
  1867.                                                         }
  1868.                                                         temp = NULL;
  1869.                                                         break;
  1870.                                                 case fc_crb :
  1871.                                                         if (preq_primitive->fc == NULL)
  1872.                                                                 preq_primitive->fc = m2m_filterCriteria_init();
  1873.                                                         strRemove(val, "crb=");
  1874.                                                         temp = strndup(val, (len-4));
  1875.                                                         if (validationCheck(crb,temp) == 1){
  1876.                                                                 preq_primitive->fc->crb = strndup(val,(len-4));
  1877.                                                                 LOG(3, "CoAP Rqp mesajı FilterCriteria CreatedBefore -->%s<--",preq_primitive->fc->crb);
  1878.                                                         }else{
  1879.                                                                 INFO("Created Before -->%s<-- not valid", temp);
  1880.                                                         }
  1881.                                                         temp = NULL;
  1882.                                                         break;
  1883.                                                 case fc_cra :
  1884.                                                         if (preq_primitive->fc == NULL)
  1885.                                                                 preq_primitive->fc = m2m_filterCriteria_init();
  1886.                                                         strRemove(val, "cra=");
  1887.                                                         temp = strndup(val, (len-4));
  1888.                                                         if (validationCheck(cra,temp) == 1){
  1889.                                                                 preq_primitive->fc->cra = strndup(val,(len-4));
  1890.                                                                 LOG(3, "CoAP Rqp mesajı FilterCriteria CreatedAfter -->%s<--",preq_primitive->fc->cra);
  1891.                                                         }else{
  1892.                                                                 INFO("Created After -->%s<-- not valid", temp);
  1893.                                                         }
  1894.                                                         temp = NULL;
  1895.                                                         break;
  1896.                                                 case fc_ms :
  1897.                                                         if (preq_primitive->fc == NULL)
  1898.                                                                 preq_primitive->fc = m2m_filterCriteria_init();
  1899.                                                         strRemove(val, "ms=");
  1900.                                                         temp = strndup(val, (len-4));
  1901.                                                         if (validationCheck(ms,temp) == 1){
  1902.                                                                 preq_primitive->fc->ms = strndup(val,(len-3));
  1903.                                                                 LOG(3, "CoAP Rqp mesajı FilterCriteria ModifiedSince -->%s<--",preq_primitive->fc->ms);
  1904.                                                         }else{
  1905.                                                                 INFO("Modified Since -->%s<-- not valid", temp);
  1906.                                                         }
  1907.                                                         temp = NULL;
  1908.                                                         break;
  1909.                                                 case fc_us :
  1910.                                                         if (preq_primitive->fc == NULL)
  1911.                                                                 preq_primitive->fc = m2m_filterCriteria_init();
  1912.                                                         strRemove(val, "us=");
  1913.                                                         temp = strndup(val, (len-4));
  1914.                                                         if (validationCheck(us,temp) == 1){
  1915.                                                                 preq_primitive->fc->us = strndup(val,(len-3));
  1916.                                                                 LOG(3, "CoAP Rqp mesajı FilterCriteria UnmodifiedSince -->%s<--",preq_primitive->fc->us);
  1917.                                                         }else{
  1918.                                                                 INFO("Unmodified Since -->%s<-- not valid", temp);
  1919.                                                         }
  1920.                                                         temp = NULL;
  1921.                                                         break;
  1922.                                                 case fc_sts :
  1923.                                                         if (preq_primitive->fc == NULL)
  1924.                                                                 preq_primitive->fc = m2m_filterCriteria_init();
  1925.                                                         strRemove(val, "sts=");
  1926.                                                         temp = strndup(val,(len-4));
  1927.                                                         if (validationCheck(sts,temp) == 1){
  1928.                                                                 preq_primitive->fc->sts = atoi(temp);
  1929.                                                                 LOG(3, "CoAP Rqp mesajı FilterCriteria StateTagSmaller -->%d<--",preq_primitive->fc->sts);
  1930.                                                         }else{
  1931.                                                                 INFO("State Tag Smaller -->%s<-- not valid", temp);
  1932.                                                         }
  1933.                                                         temp = NULL;
  1934.                                                         break;
  1935.                                                 case fc_stb :
  1936.                                                         if (preq_primitive->fc == NULL)
  1937.                                                                 preq_primitive->fc = m2m_filterCriteria_init();
  1938.                                                         strRemove(val, "stb=");
  1939.                                                         temp =  strndup(val,(len-4));
  1940.                                                         if (validationCheck(stb,temp) == 1){
  1941.                                                                 preq_primitive->fc->stb =  atoi(temp);
  1942.                                                                 LOG(3, "CoAP Rqp mesajı FilterCriteria StateTagBigger -->%d<--",preq_primitive->fc->stb);
  1943.                                                         }else{
  1944.                                                                 INFO("State Tag Bigger -->%s<-- not valid", temp);
  1945.                                                         }
  1946.                                                         temp = NULL;
  1947.                                                         break;
  1948.                                                 case fc_exb :
  1949.                                                         if (preq_primitive->fc == NULL)
  1950.                                                                 preq_primitive->fc = m2m_filterCriteria_init();
  1951.                                                         strRemove(val, "exb=");
  1952.                                                         temp =  strndup(val,(len-4));
  1953.                                                         if (validationCheck(exb,temp) == 1){
  1954.                                                                 preq_primitive->fc->exb = strndup(val,(len-4));
  1955.                                                                 LOG(3, "CoAP Rqp mesajı FilterCriteria ExpireBefore -->%s<--",preq_primitive->fc->exb);
  1956.                                                         }else{
  1957.                                                                 INFO("Expire Before -->%s<-- not valid", temp);
  1958.                                                         }
  1959.                                                         temp = NULL;
  1960.                                                         break;
  1961.                                                 case fc_exa :
  1962.                                                         if (preq_primitive->fc == NULL)
  1963.                                                                 preq_primitive->fc = m2m_filterCriteria_init();
  1964.                                                         strRemove(val, "exa=");
  1965.                                                         temp =  strndup(val,(len-4));
  1966.                                                         if (validationCheck(exa,temp) == 1){
  1967.                                                                 preq_primitive->fc->exa = strndup(val,(len-4));
  1968.                                                                 LOG(3, "CoAP Rqp mesajı FilterCriteria ExpireAfter -->%s<--",preq_primitive->fc->exa);
  1969.                                                         }else{
  1970.                                                                 INFO("Expire After -->%s<-- not valid", temp);
  1971.                                                         }
  1972.                                                         temp = NULL;
  1973.                                                         break;
  1974.                                                 case fc_lbl :
  1975.                                                         if (preq_primitive->fc == NULL)
  1976.                                                                 preq_primitive->fc = m2m_filterCriteria_init();
  1977.                                                         strRemove(val, "lbl=");
  1978.                                                         preq_primitive->fc->lbl = strndup(val,(len-4));
  1979.                                                         LOG(3, "CoAP Rqp mesajı FilterCriteria Labels -->%s<--",preq_primitive->fc->lbl);
  1980.                                                         break;
  1981.                                                 case fc_szb :
  1982.                                                         if (preq_primitive->fc == NULL)
  1983.                                                                 preq_primitive->fc = m2m_filterCriteria_init();
  1984.                                                         strRemove(val, "szb=");
  1985.                                                         temp = strndup(val,(len-4));
  1986.                                                         if (validationCheck(szb,temp) == 1){
  1987.                                                                 preq_primitive->fc->szb = atoi(temp);
  1988.                                                                 LOG(3, "CoAP Rqp mesajı FilterCriteria SizeBelow -->%d<--",preq_primitive->fc->sza);
  1989.                                                         }else{
  1990.                                                                 INFO("Size Below -->%s<-- not valid", temp);
  1991.                                                         }
  1992.                                                         temp = NULL;
  1993.                                                         break;
  1994.                                                 case fc_sza :
  1995.                                                         if (preq_primitive->fc == NULL)
  1996.                                                                 preq_primitive->fc = m2m_filterCriteria_init();
  1997.                                                         strRemove(val, "sza=");
  1998.                                                         temp = strndup(val,(len-4));
  1999.                                                         if (validationCheck(sza,temp) == 1){
  2000.                                                                 preq_primitive->fc->sza= atoi(temp);
  2001.                                                                 LOG(3, "CoAP Rqp mesajı FilterCriteria SizeAbove -->%d<--",preq_primitive->fc->szb);
  2002.                                                         }else{
  2003.                                                                 INFO("Size Above -->%s<-- not valid", temp);
  2004.                                                         }
  2005.                                                         temp = NULL;
  2006.                                                         break;
  2007.                                                 case fc_cty :
  2008.                                                         if (preq_primitive->fc == NULL)
  2009.                                                                 preq_primitive->fc = m2m_filterCriteria_init();
  2010.                                                         strRemove(val,"cty=");
  2011.                                                         preq_primitive->fc->cty = strndup(val,(len-4));
  2012.                                                         LOG(3, "CoAP Rqp mesajı FilterCriteria ContentType -->%s<--",preq_primitive->fc->cty);
  2013.                                                         break;
  2014.                                                 case fc_fu :
  2015.                                                         if (preq_primitive->fc == NULL)
  2016.                                                                 preq_primitive->fc = m2m_filterCriteria_init();
  2017.                                                         strRemove(val, "fu=");
  2018.                                                         temp = strndup(val,(len-3));
  2019.                                                         preq_primitive->fc->fu = atoi(temp);
  2020.                                                         LOG(3, "CoAP Rqp mesajı FilterCriteria FilterUsage -->%d<--",preq_primitive->fc->fu);
  2021.                                                         temp = NULL;
  2022.                                                         break;
  2023.                                                 case fc_lim :
  2024.                                                         if (preq_primitive->fc == NULL)
  2025.                                                                 preq_primitive->fc = m2m_filterCriteria_init();
  2026.                                                         strRemove(val, "lim=");
  2027.                                                         temp = strndup(val,(len-4));
  2028.                                                         if (validationCheck(lim,temp) == 1){
  2029.                                                                 preq_primitive->fc->lim = atoi(temp);
  2030.                                                                 LOG(3, "CoAP Rqp mesajı FilterCriteria Limit -->%d<--",preq_primitive->fc->lim);
  2031.                                                         }else{
  2032.                                                                 INFO("Limit -->%s<-- not valid", temp);
  2033.                                                         }
  2034.                                                         temp = NULL;
  2035.                                                         break;
  2036.                                                 case msg_drt :
  2037.                                                         strRemove(val, "drt=");
  2038.                                                         temp = strndup(val,(len-4));
  2039.                                                         if (validationCheck(drt,temp) == 1){
  2040.                                                                 preq_primitive->drt = atoi(temp);
  2041.                                                                 LOG(3, "CoAP Rqp mesajı Discovery Result Type -->%d<--",preq_primitive->drt);
  2042.                                                         }else{
  2043.                                                                 INFO("Discovery Result Type -->%s<-- not valid", temp);
  2044.                                                         }
  2045.                                                         temp = NULL;
  2046.                                                         break;
  2047.                                                 case fc_atr_nm_cr :
  2048.                                                         if (preq_primitive->fc == NULL)
  2049.                                                                 preq_primitive->fc = m2m_filterCriteria_init();
  2050.                                                         if (preq_primitive->fc->atr == NULL)
  2051.                                                                 preq_primitive->fc->atr = m2m_attribute_init();
  2052.                                                         strRemove(val,"cr=");
  2053.                                                         preq_primitive->fc->atr->nm = strdup("cr");
  2054.                                                         preq_primitive->fc->atr->val = strndup(val,(len-3));
  2055.                                                         LOG(3, "CoAP Rqp mesajı FilterCriteria Attribute Name -->%s<--",preq_primitive->fc->atr->nm);
  2056.                                                         LOG(3, "CoAP Rqp mesajı FilterCriteria Attribute Value -->%s<--",preq_primitive->fc->atr->val);
  2057.                                                         break;
  2058.                                                 case fc_atr_nm_mid :
  2059.                                                         if (preq_primitive->fc == NULL)
  2060.                                                                 preq_primitive->fc = m2m_filterCriteria_init();
  2061.                                                         if (preq_primitive->fc->atr == NULL)
  2062.                                                                 preq_primitive->fc->atr = m2m_attribute_init();
  2063.                                                         strRemove(val,"mid=");
  2064.                                                         preq_primitive->fc->atr->nm = strdup("mid");
  2065.                                                         preq_primitive->fc->atr->val = strndup(val,(len-4));
  2066.                                                         LOG(3, "CoAP Rqp mesajı FilterCriteria Attribute Name -->%s<--",preq_primitive->fc->atr->nm);
  2067.                                                         LOG(3, "CoAP Rqp mesajı FilterCriteria Attribute Value -->%s<--",preq_primitive->fc->atr->val);
  2068.                                                         break;
  2069.                                                 default :
  2070.                                                         ERR("Undefined Query option");
  2071.                                                         break;
  2072.                                         }
  2073.                                         temp = NULL;
  2074.                                         index = 0;
  2075.                                         break;
  2076.                                         /*Request massage OneM2M From parameter parse*/
  2077.                                 case oneM2M_FR :
  2078.                                         preq_primitive->fr = strndup(val,len);
  2079.                                         LOG(3, "CoAP Rqp mesajı From -->%s<--",preq_primitive->fr);
  2080.                                         break;
  2081.                                         /*Request massage OneM2M RequestIdentifier parameter parse*/
  2082.                                 case oneM2M_RQI :
  2083.                                         *rqi_hash_key = strndup(val,len);
  2084.                                         preq_primitive->rqi = strndup(val, len);
  2085.                                         LOG(3, "CoAP Rqp mesajı RequestIdentifier -->%s<--",preq_primitive->rqi);
  2086.                                         break;
  2087.                                         /*Request massage OneM2M Name parameter parse*/
  2088.                                 case oneM2M_NM :
  2089.                                         preq_primitive->nm = strndup(val, len);
  2090.                                         LOG(3, "CoAP Rqp mesajı Name -->%s<--",preq_primitive->nm);
  2091.                                         break;
  2092.                                         /*Request massage OneM2M OriginatingTimestamp parameter parse*/
  2093.                                 case oneM2M_OT :
  2094.                                         temp = strndup(val, len);
  2095.                                         if (validationCheck(ot,temp) == 1){
  2096.                                                 preq_primitive->ot = strndup(val,len);
  2097.                                                 LOG(3, "CoAP Rqp mesajı OriginatingTimestamp -->%s<---",preq_primitive->ot);
  2098.                                         }else{
  2099.                                                 INFO("Originating Timestamp -->%s<-- not valid", temp);
  2100.                                         }
  2101.                                         temp = NULL;
  2102.                                         break;
  2103.                                         /*Request massage OneM2M RequestExpirationTimestamp parameter parse*/
  2104.                                 case oneM2M_RQET :
  2105.                                         temp = strndup(val, len);
  2106.                                         if (validationCheck(rqet,temp) == 1){
  2107.                                                 preq_primitive->rqet = strndup(val,len);
  2108.                                                 LOG(3, "CoAP Rqp mesajı RequestExpirationTimestamp -->%s<--",preq_primitive->rqet);
  2109.                                         }else{
  2110.                                                 INFO("Rquest Expiration Timestamp -->%s<-- not valid", temp);
  2111.                                         }
  2112.                                         temp = NULL;
  2113.                                         break;
  2114.                                         /*Request massage OneM2M ResultExpirationTimestamp parameter parse*/
  2115.                                 case oneM2M_RSET :
  2116.                                         temp = strndup(val, len);
  2117.                                         if (validationCheck(rset,temp) == 1){
  2118.                                                 preq_primitive->rset = strndup (val,len);
  2119.                                                 LOG(3, "CoAP Rqp mesajı ResultExpirationTimestamp -->%s<--",preq_primitive->rset);
  2120.                                         }else{
  2121.                                                 INFO("Result Expiration Timestamp -->%s<-- not valid", temp);
  2122.                                         }
  2123.                                         temp = NULL;
  2124.                                         break;
  2125.                                         /*Request massage OneM2M OperationExecutionTime parameter parse*/
  2126.                                 case oneM2M_OET :
  2127.                                         temp = strndup(val, len);
  2128.                                         if (validationCheck(oet,temp) == 1){
  2129.                                                 preq_primitive->oet = strndup(val,len);
  2130.                                                 LOG(3, "CoAP Rqp mesajı OperationExecutionTime -->%s<--",preq_primitive->oet);
  2131.                                         }else{
  2132.                                                 INFO("Operation Execution Timestamp -->%s<-- not valid", temp);
  2133.                                         }
  2134.                                         temp = NULL;
  2135.                                         break;
  2136.                                         /*Request massage OneM2M NotificationURI parameter parse*/
  2137.                                 case oneM2M_RTURI :
  2138.                                         preq_primitive->rti->nu = strndup(val,len);
  2139.                                         LOG(3, "CoAP Rqp mesajı NotificationURI -->%s<--",preq_primitive->rti->nu);
  2140.                                         break;
  2141.                                         /*Request massage OneM2M EventCategory parameter parse*/
  2142.                                 case oneM2M_EC :
  2143.                                         temp = strndup(val,len);
  2144.                                         if (validationCheck(ec,temp) == 1){
  2145.                                                 preq_primitive->ec = atoi(temp);
  2146.                                                 LOG(3, "CoAP Rqp mesajı EventCategory -->%d<--",preq_primitive->ec);
  2147.                                         }else{
  2148.                                                 INFO("Event Category -->%s<-- not valid", temp);
  2149.                                         }
  2150.                                         temp = NULL;
  2151.                                         break;
  2152.                                         /*Request massage OneM2M GroupRequestIdentifier parameter parse*/
  2153.                                 case oneM2M_GID :
  2154.                                         preq_primitive->gid = strndup(val,len);
  2155.                                         LOG(3, "CoAP Rqp mesajı GroupRequestIdentifier -->%s<--",preq_primitive->gid);
  2156.                                         break;
  2157.                                 default :
  2158.                                         ERR("Undefiened COAP option -->%d<--",num);
  2159.                                         break;
  2160.                         }
  2161.                         op = coap_msg_op_get_next(op);
  2162.                 }
  2163.                 if (strcmp(preq_primitive->conf, "vnd.onem2m-preq+xml") == 0){
  2164.                         preq_primitive->pc->content = strndup(coap_msg_get_payload(request_msg), coap_msg_get_payload_len(request_msg));
  2165.                         preq_primitive->pc->ty = xmlCnt;
  2166.                         LOG(3, "Content Xml  -->%s<--", (char *)preq_primitive->pc->content);
  2167.                         if(sendRequest((void *)preq_primitive, linda_ip, atoi(linda_port), group1, COAP_SERVER_GROUP) == -1){
  2168.                                 ERR("Flat-Xml branching e gönderilemedi");
  2169.                         }
  2170.                 }else if (strcmp(preq_primitive->conf, "vnd.onem2m-preq+json") == 0){
  2171.                         preq_primitive->pc->content = strndup(coap_msg_get_payload(request_msg), coap_msg_get_payload_len(request_msg));
  2172.                         preq_primitive->pc->ty = jsonCnt;
  2173.                         LOG(3, "Content Json  -->%s<--", (char *)preq_primitive->pc->content);
  2174.                         if(sendRequest((void *)preq_primitive, linda_ip, atoi(linda_port), group1, COAP_SERVER_GROUP) == -1){
  2175.                                 ERR("Flat-Json branching e gönderilemedi");
  2176.                         }
  2177.                 }else {
  2178.                         ERR("Undefined Content Format");
  2179.                 }
  2180.         }
  2181.         return 0;
  2182. }
  2183. int response_func(coap_msg_t *response_msg){
  2184.         char *linda_buff;
  2185.         xmlBuffer *xml_buffer = xmlBufferCreate();
  2186.         int ret = 0;
  2187.         int countt,flat_index;
  2188.         linda_buff = NULL;
  2189.         /* @brief global timeout değişkenleri */
  2190.         int linda_timeout_sec = 5;
  2191.         int linda_timeout_usec = 0;
  2192.         coap_server_trans_t *trans_struct = NULL;
  2193.         ssize_t num = 0;
  2194.         int   res;
  2195.         Tag   tag;
  2196.         int   len;
  2197.         int search_check;
  2198.         char *value=NULL;
  2199.         int from_linda;
  2200.         int counter;
  2201.         bool table_check;
  2202.         char *conf_;
  2203.         char *json_buffer = NULL;
  2204.         char *rsp_uri_host = NULL;
  2205.         char *rsp_uri_port = NULL;
  2206.         char *temp = NULL;
  2207.  
  2208.         if(heap == NULL) {
  2209.                 /* flat veri değişkenlerini tanımla ve yer al */
  2210.                 heap = (heap_table_t *)heap_init(4096);
  2211.                 if(heap == NULL) {
  2212.                         LOG(3,"Bellek Bitmiş!");
  2213.                         BOCEK;
  2214.                 }
  2215.         }
  2216.         else {
  2217.                 heap_reset((void *)heap);
  2218.         }
  2219.  
  2220.         usleep(500000);
  2221.         res= linda_read(linda, linda_timeout_sec, linda_timeout_usec, &from_linda, &tag, &len, &value);
  2222.  
  2223.         if ( res < 0 ){
  2224.                 ERR( "Bağlantı Hatası.");
  2225.                 return -1;
  2226.         }
  2227.  
  2228.         if ( res == 0 ){
  2229.                 LOG(3,"süreaşımı");
  2230.         }
  2231.         /* Veri gelmiş.
  2232.            len== 0 ise linda kapanmış olabilir.
  2233.          */
  2234.         if ( len <= 0 ){
  2235.                 ERR( "Bağlantı Hatası. Mailbox Kapalı Olabilir..");
  2236.                 return -1;
  2237.         }
  2238.  
  2239.         if (len >= 4 && strncmp(value, "LL=", 3) == 0){
  2240.                 int x;
  2241.                 x= value[3]-'0';
  2242.                 if (x >= 0 && x <= 3){
  2243.                         log_level = x;
  2244.                         /* Log seviyesi değiştiğinde her durumda log seviyesi görülebilmeli. O yüzden seviye 1*/
  2245.                         LOG(1, "Log seviyesi %d yapıldı", log_level);
  2246.                 }else{
  2247.                         ERR("Log seviyesi %d range dışı. Log seviyesi default değer ile devam edecek", x);
  2248.                 }
  2249.         }
  2250.         free(linda_buff);
  2251.         if (!value)
  2252.                 ERR("Gelen veri okunamadı");
  2253.         linda_buff = malloc(len + 1);
  2254.         memcpy( linda_buff, value, len);
  2255.         linda_buff[len] = '\0';
  2256.         LOG(3, "Buf: %s",linda_buff );
  2257.  
  2258.         linda_set_heap_params((void *)heap, value, len);
  2259.         flat_index = heap->root_index;
  2260.  
  2261.         temp = getNodeValFromHeap(heap, flat_index, poa, 0);
  2262.         if(temp != NULL){
  2263.                 len = strlen(temp);
  2264.                 for (counter = 0; counter <= len; counter++){
  2265.                         if(temp[counter] == ']')
  2266.                                 break;
  2267.                 }
  2268.                 rsp_uri_host = strndup((temp+8),(counter-8));
  2269.                 rsp_uri_port = strndup((temp + (counter+2)), 4);
  2270.                 ret = coap_msg_add_op(response_msg,COAP_MSG_URI_HOST,strlen(rsp_uri_host),rsp_uri_host);/*3 nolu option set edildi*/
  2271.                 if (ret != 0)
  2272.                 {
  2273.                         LOG(3, "Response mesajı Uri-Host set edilemedi. Paket ilgili field olmadan yaratılıyor...");
  2274.                 }else{
  2275.                         LOG(3, "Response mesajı set edilen Urı-Host -->%s<--", rsp_uri_host);            
  2276.                 }
  2277.  
  2278.                 ret = coap_msg_add_op(response_msg,COAP_MSG_URI_PORT,strlen(rsp_uri_port),rsp_uri_port);/*7 nolu option set edildi*/
  2279.                 if (ret != 0)
  2280.                 {
  2281.                         LOG(3, "Response mesajı Uri-Port set edilemedi. Paket ilgili field olmadan yaratılıyor...");
  2282.                 }else{
  2283.                         LOG(3,"Response mesajı set edilen Uri-Port -->%s<--", rsp_uri_port);
  2284.                 }
  2285.                 temp = NULL;
  2286.         }else{
  2287.                 /*@todo ilgili mesajın rqi veya unique bir parametresi eklenecek*/
  2288.                 ERR("Response mesajında POA cekilemedi");
  2289.         }
  2290.  
  2291.         temp = getNodeValFromHeap(heap, flat_index, to, 0);
  2292.         if(temp != NULL){
  2293.                 ret = coap_msg_add_op(response_msg,COAP_MSG_URI_PATH,strlen(temp),temp);/*11 nolu option set edildi*/
  2294.                 if (ret != 0)
  2295.                 {
  2296.                         LOG(3, "Response mesajı TO set edilemedi. Paket ilgili field olmadan yaratılıyor...");
  2297.                 }else{
  2298.                         LOG(3,"Resposen mesajı set edilen TO -->%s<--", temp);
  2299.                 }
  2300.                 temp = NULL;
  2301.         }
  2302.  
  2303.         search_check = searchNodeInHeap(heap, flat_index, conf, 0, &countt);
  2304.         if (search_check == -1){
  2305.                 ERR("Coap Server Response verinin içinde CONF bulamadı!!!");
  2306.         }else{
  2307.                 LOG(3, "Response mesajı içinde CONF bulundu. Parse ediliyor");
  2308.                 conf_ = getNodeValFromHeap(heap, flat_index, conf, 0);
  2309.                 if(conf_ == NULL){
  2310.                         ERR("Response mesajı içinden CONF çekilemedi");
  2311.                 }else{
  2312.                         LOG(3, "Response mesajı içinden CONF çekildi -->%s<--", conf_);
  2313.                         temp = g_hash_table_lookup(hash_coap_conf,conf_);
  2314.                         ret = coap_msg_add_op(response_msg,COAP_MSG_CONTENT_FORMAT,strlen(temp),temp);/*12 nılu option set edildi*/
  2315.                         if (ret != 0){
  2316.                                 LOG(3, "Response mesajı COAP_MSG_CONTENT_FORMAT set edilemedi. Paket ilgili field olmadan yaratılıyor...");
  2317.                         }else{
  2318.                                 LOG(3, "Coap response mesajı CONF set edildi -->%s<--", temp);
  2319.                         }
  2320.                         temp=NULL;
  2321.                 }
  2322.         }
  2323.  
  2324.         temp = getNodeValFromHeap(heap, flat_index, fr, 0);
  2325.         if(temp != NULL){
  2326.                 ret = coap_msg_add_op(response_msg,oneM2M_FR,strlen(temp),temp);/*from set edildi*/
  2327.                 if (ret != 0){
  2328.                         LOG(3, "Response mesajı FROM set edilemedi. Paket ilgili field olmadan yaratılıyor...");
  2329.                 }else{
  2330.                         LOG(3, "Response mesajı FROM set edildi -->%s<--", temp);
  2331.                 }
  2332.                 temp = NULL;
  2333.         }else{
  2334.                 INFO("Response mesajında FROM bulunamadı");
  2335.         }
  2336.  
  2337.         char *rqi_;
  2338.         rqi_ = getNodeValFromHeap(heap, flat_index, rqi, 0);
  2339.         if(rqi_ != NULL){
  2340.                 LOG(3, "rqi -->%s<--", rqi_);
  2341.                 ret = coap_msg_add_op(response_msg,oneM2M_RQI,strlen(rqi_),rqi_);
  2342.                 if (ret != 0)
  2343.                 {
  2344.                         coap_msg_destroy(response_msg);
  2345.                         ERR("Response mesajı Request Identifier set edilemedi. Paket yok edildi...");
  2346.                         return ret;
  2347.                 }else{
  2348.                         LOG(3, "Response mesajı RQI set edildi -->%s<--", rqi_);
  2349.                 }
  2350.         }else{
  2351.                 INFO("Response mesajında RQI bulunamdı");
  2352.         }
  2353.  
  2354.         temp = getNodeValFromHeap(heap, flat_index, ot, 0);
  2355.         if(temp != NULL){
  2356.                 LOG(3, "ot -->%s<--", temp);
  2357.                 ret = coap_msg_add_op(response_msg,oneM2M_OT,strlen(temp),temp);/*originatingTimestamp set edildi*/
  2358.                 if (ret != 0){
  2359.                         LOG(3, "Response mesajı OriginatingTimestamp set edilemedi. Paket ilgili field olmadan yaratılıyor...");
  2360.                 }else{
  2361.                         LOG(3, "Response mesajı OT set edildi -->%s<--", temp);
  2362.                 }
  2363.                 temp = NULL;
  2364.         }else{
  2365.                 INFO("Response mesajında OT bulunamdı");
  2366.         }
  2367.  
  2368.         temp = getNodeValFromHeap(heap, flat_index, rset, 0);
  2369.         if(temp != NULL){
  2370.                 ret = coap_msg_add_op(response_msg,oneM2M_RSET,strlen(temp), temp);/*resultExpirationTimestamp set edildi*/
  2371.                 if (ret != 0)
  2372.                 {
  2373.                         LOG(3, "Response mesajı ResultExpirationTimestamp set edilemedi. Paket ilgili field olmadan yaratılıyor...");
  2374.                 }else{
  2375.                         LOG(3, "Response mesajı RSET set edildi -->%s<--", temp);
  2376.                 }
  2377.                 temp = NULL;
  2378.         }else{
  2379.                 INFO("Response mesajında RSET bulunamadı");
  2380.         }
  2381.  
  2382.         char ec_[256];
  2383.         if (getNodeIntFromHeap(heap, flat_index, ec, 0) > 0){
  2384.                 sprintf(ec_, "%d", getNodeIntFromHeap(heap, flat_index, ec, 0));
  2385.                 LOG(3, "ec -->%s<--", ec_);
  2386.                 ret = coap_msg_add_op(response_msg,oneM2M_EC,strlen(ec_),ec_);
  2387.                 if (ret != 0)
  2388.                 {
  2389.                         LOG(3, "Response mesajı eventCategory set edilemedi. Paket ilgili field olmadan yaratılıyor...");
  2390.                 }else{
  2391.                         LOG(3, "Response mesajı EC set edildi -->%s<--", ec_);
  2392.                 }
  2393.         }else{
  2394.                 INFO("Response mesajı içinde EC bulunamdı");
  2395.         }
  2396.  
  2397.         int pc_index = searchNodeInHeap(heap, flat_index, pc, 0, &countt);
  2398.         if (pc_index == -1){
  2399.                 LOG(3, "Coap Server Lindadan aldığı verinin içinde content bulamadı!!");
  2400.         }
  2401.         else if (strcmp(conf_, "vnd.onem2m-prsp+xml") == 0){
  2402.                 LOG(3, "Flat Content XML e dönüştürülecek");
  2403.  
  2404.                 /*content geldi, asagisi xml uzunluk doner*/
  2405.                 pc_index = flatten_to_xml( heap, get_heap_data(heap, pc_index), &xml_buffer);
  2406.                 if (pc_index == -1){
  2407.                         ERR("Flat content XML yapılamadı!!");
  2408.                         BOCEK;
  2409.                 }
  2410.                 else{
  2411.                         LOG(3, "Dönüş XML i \n\n%s", xml_buffer->content );
  2412.                         ret=coap_msg_set_payload(response_msg, (char *)xml_buffer->content, strlen((char *)xml_buffer->content));
  2413.                         if (ret !=0)
  2414.                         {
  2415.                                 LOG(3, "Response mesajı Content set edilemedi. Paket ilgili field olmadan yaratılıyor...");
  2416.                         }
  2417.                 }
  2418.         }else if(strcmp(conf_, "vnd.onem2m-prsp+json") == 0){
  2419.                 search_check = flatten_to_json(heap, pc_index, &json_buffer);
  2420.                 if (search_check == -1){
  2421.                         ERR("Flat content JSON yapılamadı!!!");
  2422.                         BOCEK;
  2423.                 }else{
  2424.                         LOG(3, "Dönüş JSON mesajı %s", json_buffer);
  2425.                         ret = coap_msg_set_payload(response_msg, json_buffer, strlen(json_buffer));
  2426.                         if (ret != 0){
  2427.                                 LOG(3, "Response mesajı Content set edilemedi. Paket ilgili field olmadan yaratılıyor...");
  2428.  
  2429.                         }
  2430.                 }
  2431.  
  2432.         }
  2433.         ret = coap_msg_set_type(response_msg, COAP_MSG_ACK);
  2434.         if (ret != 0)
  2435.         {
  2436.                 coap_msg_destroy(response_msg);
  2437.                 ERR("Response mesajı type set edilemedi. Paket yok edildi...");
  2438.                 return ret;
  2439.         }
  2440.  
  2441.         char rsc__[256];
  2442.         if (getNodeIntFromHeap(heap, flat_index, rsc, 0) > 0){
  2443.                 sprintf(rsc__, "%d", getNodeIntFromHeap(heap, flat_index, rsc, 0));
  2444.                 LOG(3, "rsc -->%s<--", rsc__);
  2445.                 ret = coap_msg_set_code(response_msg, atoi(g_hash_table_lookup(hash_pri_to_coap_code,rsc__)),atoi(g_hash_table_lookup(hash_pri_to_coap_detail,rsc__)));
  2446.                 if (ret != 0)
  2447.                 {
  2448.                         coap_msg_destroy(response_msg);
  2449.                         ERR("Response mesajı Status Code set edilemedi. Paket yok edildi...");
  2450.                         return ret;
  2451.                 }
  2452.                 ret = coap_msg_add_op(response_msg,oneM2M_RSC,strlen(rsc__),rsc__);
  2453.                 if (ret != 0)
  2454.                 {
  2455.                         LOG(3, "Response mesajı responseStatusCode set edilemedi. Paket ilgili field olmadan yaratılıyor...");
  2456.                 }else{
  2457.                         LOG(3, "Response mesajı RSC set edildi -->%s<--", rsc__);
  2458.                 }
  2459.         }else{
  2460.                 ERR("Response mesajı RSC okunamadı");
  2461.         }
  2462.  
  2463.         temp = getNodeValFromHeap(heap, flat_index, conf, 0);
  2464.         if(temp != NULL){
  2465.                 LOG(3, "rsp_conf -->%s<--", temp);
  2466.         }
  2467.  
  2468.         LOG(3,"Hash talblolarında aranacak olan key RQI -->%s<--",temp);
  2469.         LOG(3,"Token Hash tablosunda bulunan toplam key sayisi -->%d<--", g_hash_table_size(hash));
  2470.         if(g_hash_table_lookup(hash,rqi_)==NULL){
  2471.                 ERR("Response mesajında gelen RQI, hash tablosunda eşleşmedi");
  2472.                 return -1;
  2473.         }else{
  2474.                 char *hash_alinan=NULL;
  2475.                 hash_alinan = (char *)g_hash_table_lookup(hash,rqi_);
  2476.                 ret = coap_msg_set_token(response_msg,hash_alinan,strlen(hash_alinan));
  2477.                 if (ret != 0)
  2478.                 {
  2479.                         coap_msg_destroy(response_msg);
  2480.                         ERR("Response mesajı Token set edilemedi. Paket yok edildi...");
  2481.                         return ret;
  2482.                 }
  2483.         }
  2484.  
  2485.         LOG(3,"Trans-struct Hash tablosunda toplam bulunan key sayısı -->%d<--", g_hash_table_size(hash_table_struct));
  2486.         if(g_hash_table_lookup(hash_table_struct,rqi_)==NULL){
  2487.                 ERR("Response mesajında gelen RQI -->%s<--, hash tablosunda eşleşmedi",rqi_);
  2488.                 return -1;
  2489.         }else{
  2490.                 LOG(3, "Response mesajı RQI-->transaction structı eşleşti");
  2491.                 trans_struct =(coap_server_trans_t *) (g_hash_table_lookup(hash_table_struct, rqi_));
  2492.         }
  2493.  
  2494.         table_check=g_hash_table_remove(hash,rqi_);
  2495.  
  2496.         if(!table_check){
  2497.                 ERR("RQI -->%s<--  key olarak token hash tablosundan silinemedi!!!",rqi_);
  2498.         }else if(table_check){
  2499.                 LOG(3,"RQI -->%s<--  başarıyla token hash tablosundan silindi",rqi_)
  2500.         }
  2501.  
  2502.         table_check=g_hash_table_remove(hash_table_struct,rqi_);
  2503.  
  2504.         if(!table_check){
  2505.                 ERR("RQI -->%s<--  key olarak trans struct hash tablosundan silinemedi!!!",rqi_);
  2506.         }else if(table_check){
  2507.                 LOG(3,"RQI -->%s<--  başarıyla trans-struct hash tablosundan silindi",rqi_)
  2508.         }
  2509.  
  2510.         print_coap_msge("send:", response_msg);
  2511.  
  2512.         num = coap_server_trans_send(trans_struct, response_msg);
  2513.         if (num < 0)
  2514.         {
  2515.                 coap_server_trans_destroy(trans_struct);
  2516.                 return num;
  2517.         }
  2518.         return 0;
  2519. }
  2520. /*
  2521.  @brief Determine whether a request warrants a piggy-backed
  2522.  response or a separate response
  2523.  
  2524.  This function makes the decision on whether to send a separate
  2525.  response or a piggy-backed response by searching for the URI
  2526.  path taken from the request message structure in a user supplied
  2527.  URI path list. The idea being that some resources will consistently
  2528.  require time to retrieve and others will not.
  2529.  
  2530.  @param[in] server Pointer to a server structure
  2531.  @param[in] msg Pointer to a message structure
  2532.  
  2533.  @returns Response type
  2534.  @retval COAP_SERVER_PIGGYBACKED Piggy-backed response
  2535.  @retval COAP_SERVER_SEPARATE Separate response
  2536.  */
  2537. static int coap_server_get_resp_type(coap_server_t *server, coap_msg_t *msg)
  2538. {
  2539.         coap_msg_op_t *op = NULL;
  2540.         size_t val_len = 0;
  2541.         size_t add = 0;
  2542.         size_t len = 0;
  2543.         char val_buf[COAP_MSG_OP_URI_PATH_MAX_LEN] = {0};
  2544.         char buf[COAP_MSG_OP_URI_PATH_MAX_LEN] = {0};
  2545.         char *val = NULL;
  2546.         char *p = NULL;
  2547.         int match = 0;
  2548.         p = buf;
  2549.         len = sizeof(buf) - 1;
  2550.         op = coap_msg_get_first_op(msg);
  2551.         while (op != NULL)
  2552.         {
  2553.                 strncpy(p, "/", len);
  2554.                 add = (1 < len) ? 1 : len;
  2555.                 p += add;
  2556.                 len -= add;
  2557.                 val = coap_msg_op_get_val(op);
  2558.                 val_len = coap_msg_op_get_len(op);
  2559.                 if (val_len > sizeof(val_buf) - 1)
  2560.                         val_len = sizeof(val_buf) - 1;
  2561.                 memcpy(val_buf, val, val_len);
  2562.                 strncpy(p, val_buf, len);
  2563.                 add = (val_len < len) ? val_len : len;
  2564.                 p += add;
  2565.                 len -= add;
  2566.                 op = coap_msg_op_get_next(op);
  2567.         }
  2568.         if (p == buf)
  2569.         {
  2570.                 buf[0] = '/';
  2571.         }
  2572.         match = coap_server_path_list_match(&server->sep_list, buf);
  2573.         return match ? COAP_SERVER_SEPARATE : COAP_SERVER_PIGGYBACKED;
  2574. }
  2575. /*
  2576.  @brief Receive a request from the client and send the response
  2577.  
  2578.  @param[in,out] server Pointer to a client structure
  2579.  
  2580.  @returns Operation status
  2581.  @retval 0 Success
  2582.  @retval <0 Error
  2583.  */
  2584. int coap_server_exchange(coap_server_t *server)
  2585. {
  2586.         struct sockaddr_in6 client_sin = {0};
  2587.         coap_server_trans_t *trans = NULL;
  2588.         coap_msg_t recv_msg = {0};
  2589.         coap_msg_t send_msg = {0};
  2590.         socklen_t client_sin_len = 0;
  2591.         unsigned op_num = 0;
  2592.         ssize_t num = 0;
  2593.         int resp_type = 0;
  2594.         int ret = 0;
  2595.         bool hash_check;
  2596.         /* accept incoming connection */
  2597.         ret = coap_server_accept(server, &client_sin, &client_sin_len);
  2598.         if (ret < 0)
  2599.         {
  2600.                 return ret;
  2601.         }
  2602.  
  2603.         /* find or create transaction */
  2604.         trans = coap_server_find_trans(server, &client_sin, client_sin_len);
  2605.         if (trans == NULL)
  2606.         {
  2607.                 trans = coap_server_find_empty_trans(server);
  2608.                 if (trans == NULL)
  2609.                 {
  2610.                         trans = coap_server_find_oldest_trans(server);
  2611.                         coap_server_trans_destroy(trans);
  2612.                 }
  2613.  
  2614.                 ret = coap_server_trans_create(trans, server, &client_sin, client_sin_len);
  2615.                 if (ret < 0)
  2616.                 {
  2617.                         return ret;
  2618.                 }
  2619. #ifdef COAP_DTLS_EN
  2620.                 /* if DTLS is enabled then coap_server_trans_create has consumed */
  2621.                 /* the received data as part of the handshake, we need to wait for */
  2622.                 /* more data to arrive and identify the sender */
  2623.                 return 0;
  2624. #endif
  2625.         }
  2626.  
  2627.         coap_server_glb.poa_host=trans->client_addr;
  2628.         sprintf((char *)coap_server_glb.poa_port,"%u",ntohs(trans->client_sin.sin6_port));      
  2629.         /* receive message */
  2630.         coap_msg_create(&recv_msg);
  2631.         num = coap_server_trans_recv(trans, &recv_msg);
  2632.         if (num < 0)
  2633.         {
  2634.                 coap_msg_destroy(&recv_msg);
  2635.                 coap_server_trans_destroy(trans);
  2636.                 return num;
  2637.         }
  2638.         /* check for duplicate request */
  2639.         if (coap_server_trans_match_req(trans, &recv_msg))
  2640.         {
  2641.                 if (coap_msg_get_type(&recv_msg) == COAP_MSG_CON)
  2642.                 {
  2643.                         /* message deduplication */
  2644.                         /* acknowledge the (confirmable) request again */
  2645.                         /* do not send the response again */
  2646.                         coap_log_info("Received duplicate confirmable request from address %s and port %u", trans->client_addr, ntohs(trans->client_sin.sin6_port));
  2647.                         ret = coap_server_trans_send_ack(trans, &recv_msg);
  2648.                         coap_msg_destroy(&recv_msg);
  2649.                         if (ret < 0)
  2650.                         {
  2651.                                 coap_server_trans_destroy(trans);
  2652.                                 return ret;
  2653.                         }
  2654.                         return 0;
  2655.                 }
  2656.                 else if (coap_msg_get_type(&recv_msg) == COAP_MSG_NON)
  2657.                 {
  2658.                         /* message deduplication */
  2659.                         /* do not acknowledge the (non-confirmable) request again */
  2660.                         /* do not send the response again */
  2661.                         coap_log_info("Received duplicate non-confirmable request from address %s and port %u", trans->client_addr, ntohs(trans->client_sin.sin6_port));
  2662.                         coap_msg_destroy(&recv_msg);
  2663.                         return 0;
  2664.                 }
  2665.         }
  2666.         /* check for an ack for a previous response */
  2667.         if (coap_server_trans_match_resp(trans, &recv_msg))
  2668.         {
  2669.                 if (coap_msg_get_type(&recv_msg) == COAP_MSG_ACK)
  2670.                 {
  2671.                         /* the server must stop retransmitting its response */
  2672.                         /* on any matching acknowledgement or reset message */
  2673.                         coap_log_info("Received acknowledgement from address %s and port %u", trans->client_addr, ntohs(trans->client_sin.sin6_port));
  2674.                         ret = coap_server_trans_stop_ack_timer(trans);
  2675.                         coap_msg_destroy(&recv_msg);
  2676.                         if (ret < 0)
  2677.                         {
  2678.                                 coap_server_trans_destroy(trans);
  2679.                                 return ret;
  2680.                         }
  2681.                         return 0;
  2682.                 }
  2683.                 else if (coap_msg_get_type(&recv_msg) == COAP_MSG_RST)
  2684.                 {
  2685.                         /* the server must stop retransmitting its response */
  2686.                         /* on any matching acknowledgement or reset message */
  2687.                         coap_log_info("Received reset from address %s and port %u", trans->client_addr, ntohs(trans->client_sin.sin6_port));
  2688.                         ret = coap_server_trans_stop_ack_timer(trans);
  2689.                         coap_msg_destroy(&recv_msg);
  2690.                         if (ret < 0)
  2691.                         {
  2692.                                 coap_server_trans_destroy(trans);
  2693.                                 return ret;
  2694.                         }
  2695.                         return 0;
  2696.                 }
  2697.         }
  2698.         /* check for a valid request */
  2699.         if ((coap_msg_get_type(&recv_msg) == COAP_MSG_ACK)
  2700.                         || (coap_msg_get_type(&recv_msg) == COAP_MSG_RST)
  2701.                         || (coap_msg_get_code_class(&recv_msg) != COAP_MSG_REQ))
  2702.         {
  2703.                 ret = coap_server_trans_reject(trans, &recv_msg);
  2704.                 coap_msg_destroy(&recv_msg);
  2705.                 coap_server_trans_destroy(trans);
  2706.                 return ret;
  2707.         }
  2708.         op_num = coap_server_check_options(&recv_msg);
  2709.         if (op_num != 0)
  2710.         {
  2711.                 ret = coap_server_trans_reject_bad_option(trans, &recv_msg, op_num);
  2712.                 coap_msg_destroy(&recv_msg);
  2713.                 coap_server_trans_destroy(trans);
  2714.                 return ret;
  2715.         }
  2716.         /* clear details of the previous request/response */
  2717.         coap_server_trans_clear_req(trans);
  2718.         coap_server_trans_clear_resp(trans);
  2719.         if (coap_msg_get_type(&recv_msg) == COAP_MSG_CON)
  2720.         {
  2721.                 coap_log_info("Received confirmable request from address %s and port %u", trans->client_addr, ntohs(trans->client_sin.sin6_port));
  2722.         }
  2723.         else if (coap_msg_get_type(&recv_msg) == COAP_MSG_NON)
  2724.         {
  2725.                 coap_log_info("Received non-confirmable request from address %s and port %u", trans->client_addr, ntohs(trans->client_sin.sin6_port));
  2726.         }
  2727.         /* determine response type */
  2728.         if (coap_msg_get_type(&recv_msg) == COAP_MSG_CON)
  2729.         {
  2730.                 resp_type = coap_server_get_resp_type(server, &recv_msg);
  2731.                 if (resp_type == COAP_SERVER_SEPARATE)
  2732.                         coap_log_info("Request URI path requires a separate response to address %s and port %u", trans->client_addr, ntohs(trans->client_sin.sin6_port));
  2733.                 else
  2734.                         coap_log_info("Request URI path requires a piggy-backed response to address %s and port %u", trans->client_addr, ntohs(trans->client_sin.sin6_port));
  2735.         }
  2736.         /* send an acknowledgement if necessary */
  2737.         if ((coap_msg_get_type(&recv_msg) == COAP_MSG_CON)
  2738.                         && (resp_type == COAP_SERVER_SEPARATE))
  2739.         {
  2740.                 ret = coap_server_trans_send_ack(trans, &recv_msg);
  2741.                 if (ret < 0)
  2742.                 {
  2743.                         coap_server_trans_destroy(trans);
  2744.                         coap_msg_destroy(&recv_msg);
  2745.                         return ret;
  2746.                 }
  2747.         }
  2748.         coap_msg_op_t *op_recv = NULL;
  2749.         int true_1 =0;
  2750.         op_recv=coap_msg_get_first_op(&recv_msg);
  2751.         if(op_recv->num != 257){
  2752.                 while(true_1 == 0){
  2753.                         op_recv=coap_msg_op_get_next(op_recv);
  2754.                         if(op_recv->num == 257){
  2755.                                 true_1 = 1;
  2756.                         }
  2757.                 }
  2758.         }
  2759.  
  2760.         char *token_hash = (char *)malloc(sizeof(char)*8);
  2761.         memcpy(token_hash,coap_msg_get_token(&recv_msg),(sizeof(char))*8);
  2762.  
  2763.         ret=request_func(&recv_msg,&rqi_hash_key);
  2764.         LOG(3, "Request mesajında gelen RQI--> %s",rqi_hash_key);
  2765.  
  2766.         hash_check = g_hash_table_insert(hash, rqi_hash_key, GINT_TO_POINTER(token_hash));
  2767.         if (hash_check){
  2768.                 LOG(3,"RQI--> %s  ile TOKEN hash tablosuna eklendi",rqi_hash_key);
  2769.         }else{
  2770.                 LOG(3,"RQI--> %s daha önceden token hash tablosuna kayıt olmus, yeni value ile update edildi",rqi_hash_key);
  2771.         }
  2772.         LOG(3, "Request mesajı işlendikten sonra, token hash tablosunda bulunan toplam key sayısı %d", g_hash_table_size(hash));
  2773.  
  2774.         coap_server_trans_t *trans2 = (coap_server_trans_t *)malloc(sizeof(coap_server_trans_t));
  2775.  
  2776.         memcpy(trans2, trans, sizeof(coap_server_trans_t));
  2777.  
  2778.         hash_check = g_hash_table_insert(hash_table_struct, rqi_hash_key, GUINT_TO_POINTER(trans2));
  2779.         if (hash_check){
  2780.                 LOG(3,"RQI--> %s  ile trans-struct hash tablosuna eklendi",rqi_hash_key);
  2781.         }else{
  2782.                 LOG(3,"RQI--> %s daha önceden trans-struct hash tablosuna kayıt olmus, yeni value ile update edildi",rqi_hash_key);
  2783.         }
  2784.  
  2785.         INFO("Request mesajı işlendikten sonra, Trans-struct hash tablosunda bulunan toplam key sayısı %d", g_hash_table_size(hash_table_struct));
  2786.         ret = (*server->handle)(server, &recv_msg, &send_msg);
  2787.         return ret;
  2788. }
  2789. int coap_server_run(coap_server_t *server)
  2790. {
  2791.         int check;
  2792.         atexit(last_wish);
  2793. #ifdef MALLOC_TRACE
  2794.         mtrace();
  2795. #endif
  2796.         log_level=3;
  2797.         hash_table_struct = g_hash_table_new(g_str_hash, g_str_equal);
  2798.         hash = g_hash_table_new(g_str_hash, g_str_equal);
  2799.         hash_pri_to_coap_code = g_hash_table_new(g_str_hash, g_str_equal);
  2800.         hash_pri_to_coap_detail = g_hash_table_new(g_str_hash, g_str_equal);
  2801.         hash_coap_uri_query = g_hash_table_new(g_str_hash, g_str_equal);
  2802.         hash_coap_conf = g_hash_table_new(g_str_hash, g_str_equal);
  2803.  
  2804.         check = hash_pri_to_coap_code_init(hash_pri_to_coap_code);
  2805.         if (check < 0){
  2806.                 ERR("hash_pri_to_coap_code can not initialized ");
  2807.         }else{
  2808.                 check = hash_pri_to_coap_detail_init(hash_pri_to_coap_detail);
  2809.                 if (check < 0){
  2810.                         ERR("hash_pri_to_coap_detail can not initialized ");
  2811.                 }else{
  2812.                         check = hash_coap_uri_query_init(hash_coap_uri_query);
  2813.                         if (check < 0){
  2814.                                 ERR("hash_coap_uri_query can not initialized ");
  2815.                         }else{
  2816.                                 check = hash_coap_conf_init(hash_coap_conf);
  2817.                                 if (check < 0){
  2818.                                         ERR("hash_coap_rsc can not initialized ");
  2819.                                 }else{
  2820.                                         if ( cfg_read(config_name, config_value) < 0 ){
  2821.                                                 ERR("Sistem baslagıcında config dosyası okunamadı. Default değerler ile devam edilecek.");
  2822.                                                 /*Config_values Default values*/
  2823.                                                 config_value[0]="xmlns:m2m";
  2824.                                                 config_value[1]="http://www.onem2m.org/xml/protocols";
  2825.                                                 config_value[2]="127.0.0.1";
  2826.                                                 config_value[3]="2306";
  2827.                                         }
  2828.                                         cfg_disp(config_name, config_name, stdout);
  2829.  
  2830.                                         linda= linda_connect(linda_ip, atoi(linda_port), COAP_SERVER_GROUP, "COAP_SERVER_GROUP");
  2831.                                         if ( linda == NULL ){
  2832.                                                 ERR("Lindaya bağlanamadı!!");
  2833.                                                 return -1;
  2834.                                         }
  2835.  
  2836.                                         linda_fd = linda_get_fd(linda);
  2837.                                         LOG(3,"Linda ile bağlantılı yapılan FD numarası -->  %d",linda_fd);
  2838.                                         if ( linda_fd < 0){
  2839.                                                 ERR("Linda FD okunamadı");
  2840.                                                 return -1;
  2841.                                         }
  2842.                                         linda_rdy(linda);
  2843.  
  2844.                                         while (1){
  2845.                                                 ret = coap_server_listen(server);
  2846.                                                 if (ret < 0)
  2847.                                                 {
  2848.                                                         coap_log_error("server listen: %s", strerror(-ret));
  2849.                                                         return ret;
  2850.                                                 }      
  2851.                                         }
  2852.                                 }
  2853.                         }
  2854.                 }
  2855.         }
  2856.         return 0;
  2857. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement