yapi.c
Go to the documentation of this file.
1 /*********************************************************************
2  *
3  * $Id: yapi.c 29341 2017-11-29 10:43:43Z seb $
4  *
5  * Implementation of public entry points to the low-level API
6  *
7  * - - - - - - - - - License information: - - - - - - - - -
8  *
9  * Copyright (C) 2011 and beyond by Yoctopuce Sarl, Switzerland.
10  *
11  * Yoctopuce Sarl (hereafter Licensor) grants to you a perpetual
12  * non-exclusive license to use, modify, copy and integrate this
13  * file into your software for the sole purpose of interfacing
14  * with Yoctopuce products.
15  *
16  * You may reproduce and distribute copies of this file in
17  * source or object form, as long as the sole purpose of this
18  * code is to interface with Yoctopuce products. You must retain
19  * this notice in the distributed source file.
20  *
21  * You should refer to Yoctopuce General Terms and Conditions
22  * for additional information regarding your rights and
23  * obligations.
24  *
25  * THE SOFTWARE AND DOCUMENTATION ARE PROVIDED "AS IS" WITHOUT
26  * WARRANTY OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING
27  * WITHOUT LIMITATION, ANY WARRANTY OF MERCHANTABILITY, FITNESS
28  * FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO
29  * EVENT SHALL LICENSOR BE LIABLE FOR ANY INCIDENTAL, SPECIAL,
30  * INDIRECT OR CONSEQUENTIAL DAMAGES, LOST PROFITS OR LOST DATA,
31  * COST OF PROCUREMENT OF SUBSTITUTE GOODS, TECHNOLOGY OR
32  * SERVICES, ANY CLAIMS BY THIRD PARTIES (INCLUDING BUT NOT
33  * LIMITED TO ANY DEFENSE THEREOF), ANY CLAIMS FOR INDEMNITY OR
34  * CONTRIBUTION, OR OTHER SIMILAR COSTS, WHETHER ASSERTED ON THE
35  * BASIS OF CONTRACT, TORT (INCLUDING NEGLIGENCE), BREACH OF
36  * WARRANTY, OR OTHERWISE.
37  *
38  *********************************************************************/
39 #define __FILE_ID__ "yapi"
40 #include "yapi.h"
41 #include "yproto.h"
42 #include "yhash.h"
43 #include "yjson.h"
44 #include "yprog.h"
45 
46 #ifdef WINDOWS_API
47 #include <time.h>
48 #else
49 #include <sys/time.h>
50 #endif
51 
52 static YRETCODE yapiUpdateDeviceList_internal(u32 forceupdate, char *errmsg);
53 static void yapiUnregisterHub_internal(const char *url);
54 static YRETCODE yapiPreregisterHub_internal(const char *url, char *errmsg);
55 static YRETCODE yapiHandleEvents_internal(char *errmsg);
56 static YRETCODE yapiHTTPRequestAsyncEx_internal(int tcpchan, const char *device, const char *request, int len, yapiRequestAsyncCallback callback, void *context, char *errmsg);
57 
58 //#define DEBUG_YAPI_REQ
59 
60 
61 #ifdef DEBUG_YAPI_REQ
62 
63 #include <direct.h>
64 #include <stdio.h>
65 static int global_req_count = 0;
66 
67 static int write_onfile(int fileno, char *mode, const char *firstline, int firstline_len, const char * buffer, int bufferlen)
68 {
69  char filename[128];
70  FILE *f;
71  int retry_count = 1;
72  YSPRINTF(filename, 128,"req_trace\\req_%03d.bin", fileno);
73  // write on file
74 retry:
75  if (YFOPEN(&f, filename, mode) != 0) {
76  if (retry_count--){
77  _mkdir("req_trace");
78  goto retry;
79  }
80  return -1;
81  }
82  fwrite(firstline, 1, firstline_len, f);
83  if (buffer) {
84  fwrite(buffer, 1, bufferlen, f);
85  }
86  fclose(f);
87  return 0;
88 }
89 
90 
91 #define FILE_NO_BIT_MASK 0XFFF
92 
93 static int YREQ_LOG_START(const char *msg, const char *device, const char * request, int requestsize)
94 {
95  char buffer[2048], buffer2[64];
96  struct tm timeinfo;
97  time_t rawtime;
98  int threadIdx, count, first_len;
99 
100  //we may need to add mutex here
101  count = global_req_count++;
102  int fileno = count & FILE_NO_BIT_MASK;
103  // compute time string
104  time(&rawtime);
105  localtime_s(&timeinfo, &rawtime);
106  strftime(buffer2, sizeof(buffer2), "%Y-%m-%d %H:%M:%S", &timeinfo);
107  //format first info line
108  threadIdx = yThreadIndex();
109  first_len = YSPRINTF(buffer, 2048, "[%s/%"FMTu64"](%d):no=%d = %s on %s\n",buffer2, yapiGetTickCount(), threadIdx, count, msg, device);
110  write_onfile(fileno, "wb", buffer, first_len, request, requestsize);
111  return count;
112 }
113 
114 static int YREQ_LOG_APPEND(int count, const char *msg, const char * response, int responsesize, u64 start_tm)
115 {
116  char buffer[2048], buffer2[64];
117  struct tm timeinfo;
118  time_t rawtime;
119  int threadIdx, first_len;
120 
121  //we may need to add mutex here
122  int fileno = count & FILE_NO_BIT_MASK;
123  // compute time string
124  time(&rawtime);
125  localtime_s(&timeinfo, &rawtime);
126  strftime(buffer2, sizeof(buffer2), "%Y-%m-%d %H:%M:%S", &timeinfo);
127  //format first info line
128  threadIdx = yThreadIndex();
129  first_len = YSPRINTF(buffer, 2048, "[%s/%"FMTu64"](%d):no=%d : %s responsesize=%d\n",buffer2, yapiGetTickCount() - start_tm, threadIdx, count, msg, responsesize);
130  // write on file
131  write_onfile(fileno, "ab", buffer, first_len, response, responsesize);
132  return count;
133 }
134 
135 static int YREQ_LOG_APPEND_ERR(int count, const char *msg, const char *errmsg, int error, u64 start_tm)
136 {
137  char buffer[2048], buffer2[64];
138  struct tm timeinfo;
139  time_t rawtime;
140  int threadIdx, first_len;
141 
142  //we may need to add mutex here
143  int fileno = count & FILE_NO_BIT_MASK;
144  // compute time string
145  time(&rawtime);
146  localtime_s(&timeinfo, &rawtime);
147  strftime(buffer2, sizeof(buffer2), "%Y-%m-%d %H:%M:%S", &timeinfo);
148  //format first info line
149  threadIdx = yThreadIndex();
150  first_len = YSPRINTF(buffer, 2048, "[%s/%"FMTu64"](%d):no=%d : %s errmsg(%d)=%s\n", buffer2, yapiGetTickCount()- start_tm, threadIdx, count, msg, error, errmsg);
151  // write on file
152  write_onfile(fileno, "ab", buffer, first_len, NULL, 0);
153  return count;
154 }
155 #endif
156 
157 
158 //#define DEBUG_CALLBACK
159 
160 #ifdef DEBUG_CALLBACK
161 
162 
163 #include <direct.h>
164 static int global_callback_count = 0;
165 
166 static write_cb_onfile(YAPI_FUNCTION fundescr, const char *value)
167 {
168  char filename[128];
169  FILE *f;
170  int retry_count = 1;
171  int fileno = global_callback_count >> 16;
172  char *mode ="ab";
173  char buffer[2048], buffer2[64];
174  struct tm timeinfo;
175  time_t rawtime;
176  int threadIdx, bufferlen;
177  char serial[YOCTO_SERIAL_LEN], funcId[YOCTO_FUNCTION_LEN];
178 
179  if ((global_callback_count & 0xffff) == 0) {
180  mode = "wb";
181  }
182 
183  YSPRINTF(filename, 128,"callback_trace\\callback_%d.txt", fileno);
184  // compute time string
185  time(&rawtime);
186  localtime_s(&timeinfo, &rawtime);
187  strftime(buffer2, sizeof(buffer2), "%Y-%m-%d %H:%M:%S", &timeinfo);
188  //format first info line
189  threadIdx = yThreadIndex();
190  if (value == NULL){
191  value = "(NULL)";
192  }
193  if(ypGetFunctionInfo(fundescr, serial, funcId, NULL, NULL) < 0){
194  bufferlen = YSPRINTF(buffer, 2048, "[%s/%"FMTu64"](%d):no=%d : invalid function ID (%X)\n",buffer2, yapiGetTickCount(), threadIdx, global_callback_count, fundescr);
195  }else {
196  bufferlen = YSPRINTF(buffer, 2048, "[%s/%"FMTu64"](%d):no=%d : %s.%s (%X)=%s\n",buffer2, yapiGetTickCount(), threadIdx, global_callback_count, serial,funcId, fundescr, value);
197  }
198  global_callback_count++;
199 
200 
201  // write on file
202 retry:
203  if (YFOPEN(&f, filename, mode) != 0) {
204  if (retry_count--){
205  _mkdir("callback_trace");
206  goto retry;
207  }
208  return -1;
209  }
210  fwrite(buffer, 1, bufferlen, f);
211  fclose(f);
212  return 0;
213 }
214 
215 static write_timedcb_onfile(YAPI_FUNCTION fundescr, double deviceTime, const u8 *report, u32 len)
216 {
217  char buffer[256];
218  YSPRINTF(buffer, 2048, "Timed %f %p:%u",deviceTime, report, len);
219  return write_cb_onfile(fundescr, buffer);
220 }
221 
222 #endif
223 
224 
225 void yFunctionUpdate(YAPI_FUNCTION fundescr, const char *value)
226 {
229 #ifdef DEBUG_CALLBACK
230  write_cb_onfile(fundescr, value);
231 #endif
232  yContext->functionCallback(fundescr, value);
234  }
235 }
236 
237 void yFunctionTimedUpdate(YAPI_FUNCTION fundescr, double deviceTime, const u8 *report, u32 len)
238 {
241 #ifdef DEBUG_CALLBACK
242  write_timedcb_onfile(fundescr, deviceTime, report, len);
243 #endif
244  yContext->timedReportCallback(fundescr, deviceTime, report, len);
246  }
247 }
248 
249 
250 /*****************************************************************************
251  Internal functions for hub enumeration
252  ****************************************************************************/
253 
254 typedef enum
255 {
284 
285 
286 #ifdef DEBUG_NET_ENUM
287 const char * ENU_PARSE_STATE_STR[]=
288 {
289  "ENU_HTTP_START",
290  "ENU_SERVICE",
291  "ENU_WP_START",
292  "ENU_WP_ARRAY",
293  "ENU_WP_ENTRY",
294  "ENU_WP_SERIAL",
295  "ENU_WP_LOGICALNAME",
296  "ENU_WP_PRODUCTNAME",
297  "ENU_WP_PRODUCTID",
298  "ENU_WP_DEVURL",
299  "ENU_WP_BEACON",
300  "ENU_WP_INDEX",
301  "ENU_YP_CONTENT",
302  "ENU_YP_TYPE",
303  "ENU_YP_TYPE_LIST",
304  "ENU_YP_ARRAY",
305  "ENU_YP_ENTRY",
306  "ENU_YP_HARDWAREID",
307  "ENU_YP_LOGICALNAME",
308  "ENU_YP_PRODUCTNAME",
309  "ENU_YP_ADVERTISEDVALUE",
310  "ENU_YP_INDEX"
311 };
312 #endif
313 
314 typedef struct {
316  ENU_PARSE_STATE state;
319  union {
320  struct {
324  s8 beacon;
325  u8 devYdx;
326  };
327  struct{
330  char advertisedValue[YOCTO_PUBVAL_LEN];
332  u8 funYdx;
333  };
334  };
337 }ENU_CONTEXT;
338 
339 
340 // return 1 -> if this we should use devUrl instead of registered URL
341 static int wpSafeCheckOverwrite(yUrlRef registeredUrl, HubSt *hub, yUrlRef devUrl)
342 {
343 
344  yAsbUrlType urlType = yHashGetUrlPort(devUrl, NULL, NULL, NULL, NULL, NULL);
345  yAsbUrlType registeredType;
346 
347  if (urlType ==USB_URL){
348  // no USB device can unregister previous devices
349 #ifdef DEBUG_WP
350  dbglog("no USB device can unregister previous devices ( 0x%X) \n",devUrl);
351 #endif
352  return 0;
353  }
354  registeredType = yHashGetUrlPort(registeredUrl, NULL, NULL, NULL, NULL, NULL);
355  if(registeredType ==USB_URL){
356 #ifdef DEBUG_WP
357  dbglog("unregister same device connected by USB ( 0x%X vs 0x%X) \n",devUrl,hub->url);
358 #endif
359  return 1;
360  }else{
361  if (registeredUrl != devUrl){
362  if( devUrl == hub->url){
363 #ifdef DEBUG_WP
364  dbglog("unregister same device connected by a VirtualHub (0x%X vs 0x%X) \n",devUrl,hub->url);
365 #endif
366  return 1;
367  }
368  }
369  }
370  return 0;
371 }
372 
373 
374 
375 /*****************************************************************************
376  * Generic device information stuff
377  ***************************************************************************/
378 
379 void initDevYdxInfos(int devYdx, yStrRef serial)
380 {
381  yGenericDeviceSt *gen = yContext->generic_infos + devYdx;
383  memset(gen,0, sizeof(yGenericDeviceSt));
384  gen->serial = serial;
386 }
387 
388 void freeDevYdxInfos(int devYdx)
389 {
390  yGenericDeviceSt *gen = yContext->generic_infos + devYdx;
394 }
395 
396 static void logResult(void *context, const u8 *result, u32 resultlen, int retcode, const char *errmsg)
397 {
398  char buffer[512];
399  yGenericDeviceSt *gen = (yGenericDeviceSt*) context;
400  int poslen;
401  const char * p = (char*) result;
402  const char * start = (char*) result;
403 
404  if (yContext == NULL || yContext->logDeviceCallback == NULL)
405  return;
406 
407  if (resultlen < 4) {
408  return; //invalid packet
409  }
410 
411  if (result==NULL || start[0] != 'O' || start[1] != 'K'){
412  return; // invalid response
413  }
414  // drop http header
415  while (resultlen >= 4) {
416  if (p[0] == '\r' && p[1] == '\n' && p[2] == '\r' && p[3] == '\n'){
417  resultlen -= 4;
418  p += 4;
419  break;
420  }
421  p++;
422  resultlen--;
423  }
424  start = p;
425  //look of '@pos'
426  p = start + resultlen - 1;
427  poslen = 0;
428  while (p > start && *p != '@'){
429  if (*p <'0' || *p > '9'){
430  poslen = 0;
431  } else{
432  poslen++;
433  }
434  p--;
435  resultlen--;
436  }
437 
438  if (*p != '@' ) {
439  return;
440  }
441 
442  memcpy(buffer, p+1, poslen);
443  buffer[poslen] = '\0';
444  //remove empty line before @pos
445  if (resultlen == 0)
446  return;
447  resultlen-=2;
448  p = start;
450  gen->deviceLogPos = atoi(buffer);
452  while (resultlen) {
453  if (*p == '\n'){
454  int linelen = (int)(p - start);
455  memcpy(buffer, start, linelen);
456  buffer[linelen] = '\0';
457  //dbglog("log:[%s]\n", buffer);
458  yContext->logDeviceCallback(gen->serial, buffer);
459  start = p + 1;
460  }
461  p++;
462  resultlen--;
463  }
467 }
468 
469 static int yapiRequestOpenWS(YIOHDL_internal *iohdl, HubSt *hub, YAPI_DEVICE dev, int tcpchan, const char *request, int reqlen, u64 mstimeout, yapiRequestAsyncCallback callback, void *context, RequestProgress progress_cb, void *progress_ctx, char *errmsg);
470 static int yapiRequestOpenHTTP(YIOHDL_internal *iohdl, HubSt *hub, YAPI_DEVICE dev, const char *request, int reqlen, int wait_for_start, u64 mstimeout, yapiRequestAsyncCallback callback, void *context, char *errmsg);
471 static int yapiRequestOpenUSB(YIOHDL_internal *iohdl, HubSt *hub, YAPI_DEVICE dev, const char *request, int reqlen, u64 unused_timeout, yapiRequestAsyncCallback callback, void *context, char *errmsg);
472 
473 
475 {
476  YRETCODE res;
477  int used;
478  char rootdevice[YOCTO_SERIAL_LEN];
479  char request[512];
480  int reqlen;
481  char errmsg[YOCTO_ERRMSG_LEN];
482  char *p;
483  YAPI_DEVICE dev;
484  u32 logPos;
485  int doPull=0;
486  yGenericDeviceSt *gen;
487  yStrRef serialref;
488  YIOHDL_internal iohdl;
489  yUrlRef url;
490  yAsbUrlProto proto;
491  int i;
492  HubSt *hub = NULL;
493 
495  gen = yContext->generic_infos + devydx;
496  if ( (gen->flags & DEVGEN_LOG_ACTIVATED) &&
497  (gen->flags & DEVGEN_LOG_PENDING) &&
498  (gen->flags & DEVGEN_LOG_PULLING)==0) {
499  doPull=1;
500  gen->flags |= DEVGEN_LOG_PULLING;
501  }
502  logPos = gen->deviceLogPos;
503  serialref = gen->serial;
505  if (serialref == YSTRREF_EMPTY_STRING || !doPull) {
506  return YAPI_SUCCESS;
507  }
508  dev = wpSearchEx(serialref);
509  YSTRCPY(request, 512, "GET ");
510  p= request + 4;
511  res = yapiGetDevicePath(dev, rootdevice, p, 512-5, NULL, errmsg);
512  if(YISERR(res)) {
513  dbglog(errmsg);
514  if (res != YAPI_DEVICE_NOT_FOUND) {
516  gen->flags &= ~DEVGEN_LOG_PULLING;
518  }
519  return res;
520  }
521  used = YSTRLEN(request);
522  p = request + used;
523  reqlen = YSPRINTF(p, 512 - used, "logs.txt?pos=%d\r\n\r\n", logPos);
524  memset(&iohdl, 0, sizeof(YIOHDL_internal));
525  // compute request timeout
526  // dispatch request on correct hub (or pseudo usb HUB)
527  url = wpGetDeviceUrlRef(dev);
528 
529  switch (yHashGetUrlPort(url, NULL, NULL, &proto, NULL, NULL)) {
530  case USB_URL:
531  res = yapiRequestOpenUSB(&iohdl, NULL, dev, request, reqlen, YIO_10_MINUTES_TCP_TIMEOUT, logResult, (void*)gen, errmsg);
532  break;
533  default:
534  for (i = 0; i < NBMAX_NET_HUB; i++) {
535  if (yContext->nethub[i] && yHashSameHub(yContext->nethub[i]->url, url)) {
536  hub = yContext->nethub[i];
537  break;
538  }
539  }
540  if (hub == NULL) {
542  } else {
543  if (proto == PROTO_WEBSOCKET) {
544  res = yapiRequestOpenWS(&iohdl, hub, dev, 0, request, reqlen, YIO_10_MINUTES_TCP_TIMEOUT, logResult, (void*)gen, NULL, NULL, errmsg);
545  } else {
546  res = yapiRequestOpenHTTP(&iohdl, hub, dev, request, reqlen, 0, YIO_10_MINUTES_TCP_TIMEOUT, logResult, (void*)gen, errmsg);
547  }
548  }
549  }
550 
551  if (YISERR(res)) {
552  if (res != YAPI_DEVICE_NOT_FOUND && res!= YAPI_DEVICE_BUSY) {
554  gen->flags &= ~DEVGEN_LOG_PULLING;
556  }
557  return res;
558  }
559  return res;
560 }
561 
562 
563 YRETCODE yapiPullDeviceLog(const char *serial)
564 {
565  YAPI_DEVICE dev;
566  int devydx;
567  dev = wpSearch(serial);
568 
569  devydx = wpGetDevYdx(dev % 0xffff);
570  if (devydx<0){
571  return YAPI_DEVICE_NOT_FOUND;
572  }
573  return yapiPullDeviceLogEx(devydx);
574 }
575 
576 
577 
578 /*****************************************************************************
579  Function:
580  void wpSafeRegister( yUrlRef hubUrl, u8 devYdx, yStrRef serialref,yStrRef lnameref, yStrRef productref, u16 deviceid, yUrlRef devUrl,s8 beacon)
581 
582  Description:
583  Register a new device into whites page (and yellow page of the module function ). This function
584  will call the arrivalCallback. This function will work for usb and TCP
585  it will check if this arrival should be dropped (if an hub is connected by usb and ip)
586 
587  Parameters:
588  NetHubSt *hub : HUB used to access the device (for USB this MUSB be NULL)
589  u8 devYdx : the devYdy relative to the hub (for usb this MUST be MAX_YDX_PER_HUB)
590  yStrRef serialref : the serial of the device
591  yStrRef lnameref : the logical name of the device
592  yStrRef productref : the product name of the device
593  u16 deviceid : the deviceid of the device
594  yUrlRef devUrl : the url of the device (not the one of the hub).
595  s8 beacon : the beacon state
596 {
597 
598  ***************************************************************************/
599 void wpSafeRegister(HubSt *hub, u8 devYdx, yStrRef serialref,yStrRef lnameref, yStrRef productref, u16 deviceid, yUrlRef devUrl,s8 beacon)
600 {
601 
602  yUrlRef registeredUrl = wpGetDeviceUrlRef(serialref);
603 #ifdef DEBUG_WP
604  {
605  if (hub == NULL){
606  dbglog("SAFE WP: register %s(0x%X) form USB\n",yHashGetStrPtr(serialref),serialref);
607  } else {
608  char host[YOCTO_HOSTNAME_NAME];
609  u16 port;
610  yAsbUrlType type = yHashGetUrlPort(hub->url,host,&port);
611  dbglog("SAFE WP: register %s(0x%X) from %s:%u\n",yHashGetStrPtr(serialref),serialref,host,port);
612  dbglog("url : hub = %d dev =%d\n",hub->url,devUrl);
613  }
614 
615  }
616  dbglog("name : %s(0x%X)\n",yHashGetStrPtr(lnameref),lnameref);
617  dbglog("product : %s(0x%X)\n",yHashGetStrPtr(productref),productref);
618  dbglog("device : %x (%d)\n",deviceid,beacon);
619 #endif
620 
621  if( registeredUrl != INVALID_HASH_IDX && wpSafeCheckOverwrite(registeredUrl,hub,devUrl)){
622  wpSafeUnregister(serialref);
623  }
624  wpRegister(-1, serialref, lnameref, productref, deviceid,devUrl,beacon);
626  if(hub && devYdx < MAX_YDX_PER_HUB) {
627  // Update hub-specific devYdx mapping between enus->devYdx and our wp devYdx
628  hub->devYdxMap[devYdx] = wpGetDevYdx(serialref);
629  }
630  // Forward high-level notification to API user
631  if (yContext->arrivalCallback) {
633  yContext->arrivalCallback(serialref);
635  }
636 }
637 
638 
639 
640 /*****************************************************************************
641  Function:
642  void wpSafeUpdate( yUrlRef hubUrl,u8 devYdx, yStrRef serialref,yStrRef lnameref, yUrlRef devUrl, s8 beacon)
643 
644  Description:
645  Update whites page (and yellow page of the module function ). This function
646  will call the changeCallback if needed. This function will work for usb and TCP
647  it will check if this update should be dropped (if an hub is connected by usb and ip)
648 
649  Parameters:
650  For TCP:
651  NetHubSt *hub : HUB used to access the device (for USB this MUSB be NULL)
652  u8 devYdx : the devYdy relative to the hub (for usb this MUST be MAX_YDX_PER_HUB)
653  yStrRef serialref : the serial of the device
654  yStrRef lnameref : the logical name of the device
655  yUrlRef devUrl : the url of the device (not the one of the hub).
656  s8 beacon : the beacon state
657 
658  ***************************************************************************/
659 void wpSafeUpdate(HubSt *hub,u8 devYdx, yStrRef serialref,yStrRef lnameref, yUrlRef devUrl, s8 beacon)
660 {
661 
662  yUrlRef registeredUrl =wpGetDeviceUrlRef(serialref);
663 #ifdef DEBUG_WP
664  {
665  if (hub == NULL){
666  dbglog("SAFE WP: update %s(0x%X) form USB\n",yHashGetStrPtr(serialref),serialref);
667  } else {
668  char host[YOCTO_HOSTNAME_NAME];
669  u16 port;
670  yAsbUrlType type = yHashGetUrlPort(hub->url,host,&port);
671  dbglog("SAFE WP: update %s(0x%X) from %s:%u\n",yHashGetStrPtr(serialref),serialref,host,port);
672  dbglog("url : hub = %d dev =%d\n",hub->url,devUrl);
673  }
674  }
675  dbglog("name : %s(0x%X)\n",yHashGetStrPtr(lnameref),lnameref);
676  dbglog("product : INVALID_HASH_IDX\n");
677  dbglog("device : %x (%d)\n",0,beacon);
678 #endif
679 
680  if( registeredUrl != INVALID_HASH_IDX && wpSafeCheckOverwrite(registeredUrl,hub,devUrl)){
681 #ifdef DEBUG_WP
682  dbglog("SAFE WP: drop update %s(0x%X)\n",yHashGetStrPtr(serialref),serialref);
683 #endif
684  return;
685  }
686  if (wpRegister(-1, serialref, lnameref, INVALID_HASH_IDX, 0, devUrl, beacon)) {
688  if(hub && devYdx < MAX_YDX_PER_HUB) {
689  // Update hub-specific devYdx mapping between enus->devYdx and our wp devYdx
690  hub->devYdxMap[devYdx] = wpGetDevYdx(serialref);
691  }
692  // Forward high-level notification to API user
695  yContext->changeCallback(serialref);
697  }
698  }
699 }
700 
701 
702 
703 void wpSafeUnregister(yStrRef serialref)
704 {
706  if(wpMarkForUnregister(serialref)){
707  // Forward high-level notification to API user before deleting data
708  if (yContext->removalCallback) {
710  yContext->removalCallback(serialref);
712  }
713  }
715 }
716 
717 static void parseNetWpEntry(ENU_CONTEXT *enus)
718 {
719  int i;
720 
721  for(i=0; i<enus->nbKnownDevices ; i++){
722  if(enus->knownDevices[i] != INVALID_HASH_IDX &&
723  enus->knownDevices[i] == enus->serial){
724  // mark the device as present (we sweep it later)
725 #ifdef DEBUG_WP
726  dbglog("parseNetWpEntry %X was present\n",enus->serial);
727 #endif
728  enus->knownDevices[i] = INVALID_HASH_IDX;
729  break;
730  }
731  }
732 
733  if(i==enus->nbKnownDevices){
734  wpSafeRegister(enus->hub,enus->devYdx,enus->serial,enus->logicalName,enus->productName,enus->productId,enus->hubref,enus->beacon);
735  } else{
736  wpSafeUpdate(enus->hub,enus->devYdx,enus->serial, enus->logicalName, enus->hubref, enus->beacon);
737  }
738 }
739 
740 static void unregisterNetDevice(yStrRef serialref)
741 {
742  int devydx;
743 
744  if(serialref == INVALID_HASH_IDX) return;
745  // Free device tcp structure, if needed
746  devydx = wpGetDevYdx(serialref);
747  if(devydx >= 0 && yContext->tcpreq[devydx]) {
748  yReqFree(yContext->tcpreq[devydx]);
749  yContext->tcpreq[devydx] = NULL;
750  }
751  wpSafeUnregister(serialref);
752 }
753 
754 static void ypUpdateNet(ENU_CONTEXT *enus)
755 {
756  if(ypRegister(enus->ypCateg, enus->serial, enus->funcId, enus->logicalName, enus->funClass, enus->funYdx, enus->advertisedValue)){
757  // Forward high-level notification to API user
758  yFunctionUpdate(((s32)enus->funcId << 16) | enus->serial,enus->advertisedValue);
759  }
760 }
761 
762 
764 {
765  char *point;
766 #ifdef DEBUG_NET_ENUM
767  //dbglog("%s: %s %s\n",ENU_PARSE_STATE_STR[enus->state],yJsonStateStr[j->st],j->token);
768 #endif
769  switch(enus->state){
770  case ENU_HTTP_START:
771  if(j->st != YJSON_HTTP_READ_CODE || YSTRCMP(j->token,"200")){
772  return YAPI_IO_ERROR;
773  }
774  enus->state = ENU_API;
775  break;
776  case ENU_API:
777  if(j->st !=YJSON_PARSE_MEMBNAME)
778  break;
779  if(YSTRCMP(j->token,"network")==0){
780  enus->state = ENU_NETWORK_START;
781  } else if(YSTRCMP(j->token,"services")==0){
782  enus->state = ENU_SERVICE;
783  } else{
784  yJsonSkip(j,1);
785  }
786  break;
787  case ENU_NETWORK_START:
788  if(j->st == YJSON_PARSE_STRUCT){
789  enus->state = ENU_NETWORK;
790  }
791  break;
792  case ENU_NETWORK:
793  if(j->st == YJSON_PARSE_STRUCT){
794  enus->state = ENU_API;
795  } else if(j->st == YJSON_PARSE_MEMBNAME){
796  if(YSTRCMP(j->token,"adminPassword")==0){
797  enus->state = ENU_NET_ADMINPWD;
798  } else{
799  yJsonSkip(j,1);
800  }
801  }
802  break;
803  case ENU_NET_ADMINPWD:
804  NETENUMLOG("adminpwd is set to [%s]\n",j->token);
805  enus->hub->writeProtected = (j->token[0] != 0);
806  enus->state = ENU_NETWORK;
807  break;
808  case ENU_SERVICE:
809  if(j->st !=YJSON_PARSE_MEMBNAME)
810  break;
811  if(YSTRCMP(j->token,"whitePages")==0){
812  enus->state = ENU_WP_START;
813  } else if(YSTRCMP(j->token,"yellowPages")==0){
814  enus->state = ENU_YP_CONTENT;
815  } else{
816  yJsonSkip(j,1);
817  }
818  break;
819  case ENU_WP_START:
820  if(j->st ==YJSON_PARSE_ARRAY){
821  enus->state = ENU_WP_ARRAY;
822  }
823  break;
824  case ENU_WP_ARRAY:
825  if(j->st == YJSON_PARSE_STRUCT){
826  enus->state = ENU_WP_ENTRY;
827  enus->serial = INVALID_HASH_IDX;
830  enus->productId = 0;
831  enus->hubref = INVALID_HASH_IDX;
832  enus->beacon = 0;
833  enus->devYdx = -1;
834  }else if(j->st ==YJSON_PARSE_ARRAY){
835  enus->state=ENU_SERVICE;
836  }else{
837  NETENUMLOG("Unknown token %s\n",j->token);
838  }
839  break;
840  case ENU_WP_ENTRY:
841  if(j->st ==YJSON_PARSE_STRUCT){
842  parseNetWpEntry(enus);
843  enus->state = ENU_WP_ARRAY;
844  }else if(j->st ==YJSON_PARSE_MEMBNAME){
845  if(YSTRCMP(j->token,"serialNumber")==0){
846  enus->state = ENU_WP_SERIAL;
847  } else if(YSTRCMP(j->token,"logicalName")==0){
848  enus->state = ENU_WP_LOGICALNAME;
849  } else if(YSTRCMP(j->token,"productName")==0){
850  enus->state = ENU_WP_PRODUCTNAME;
851  } else if(YSTRCMP(j->token,"productId")==0){
852  enus->state = ENU_WP_PRODUCTID;
853  } else if(YSTRCMP(j->token,"networkUrl")==0){
854  enus->state = ENU_WP_DEVURL;
855  } else if(YSTRCMP(j->token,"beacon")==0){
856  enus->state = ENU_WP_BEACON;
857  } else if(YSTRCMP(j->token,"index")==0){
858  enus->state = ENU_WP_INDEX;
859  } else{
860  yJsonSkip(j,1);
861  }
862  }
863  break;
864  case ENU_WP_SERIAL:
865  NETENUMLOG("set serial to %s\n",j->token);
866  enus->serial = yHashPutStr(j->token);
867  enus->state = ENU_WP_ENTRY;
868  break;
869  case ENU_WP_LOGICALNAME:
870  NETENUMLOG("set Logical name to %s\n",j->token);
871  enus->logicalName = yHashPutStr(j->token);
872  enus->state = ENU_WP_ENTRY;
873  break;
874  case ENU_WP_PRODUCTNAME:
875  NETENUMLOG("set Product name to %s\n",j->token);
876  enus->productName = yHashPutStr(j->token);
877  enus->state = ENU_WP_ENTRY;
878  break;
879  case ENU_WP_PRODUCTID:
880  NETENUMLOG("set productid to %s\n",j->token);
881  enus->productId = atoi(j->token);
882  enus->state = ENU_WP_ENTRY;
883  break;
884  case ENU_WP_DEVURL:
885  NETENUMLOG("set url to %s\n",j->token);
886  if (YSTRCMP(j->token, "/api") == 0){
887  enus->hub->serial = enus->serial;
888  }
889  enus->hubref = yHashUrlFromRef(enus->hub->url, j->token);
890  enus->state = ENU_WP_ENTRY;
891  break;
892  case ENU_WP_BEACON:
893  NETENUMLOG("set beacon to %s\n",j->token);
894  enus->beacon = atoi(j->token);
895  enus->state = ENU_WP_ENTRY;
896  break;
897  case ENU_WP_INDEX:
898  NETENUMLOG("set devYdx to %s\n",j->token);
899  enus->devYdx = atoi(j->token);
900  enus->state = ENU_WP_ENTRY;
901  break;
902  case ENU_YP_CONTENT:
903  if(j->st == YJSON_PARSE_STRUCT){
904  enus->state = ENU_YP_TYPE;
905  enus->ypCateg = INVALID_HASH_IDX;
906  }else{
907  NETENUMLOG("Unknown token %s\n",j->token);
908  }
909  break;
910  case ENU_YP_TYPE:
911  if(j->st ==YJSON_PARSE_STRUCT){
912  enus->state = ENU_SERVICE;
913  }else if(j->st ==YJSON_PARSE_MEMBNAME){
914  enus->ypCateg = yHashPutStr(j->token);
915  NETENUMLOG("Categ = %s\n",j->token);
916  enus->state = ENU_YP_TYPE_LIST;
917  }else{
918  NETENUMLOG("Unknown token %s\n",j->token);
919  }
920  break;
921  case ENU_YP_TYPE_LIST:
922  if(j->st ==YJSON_PARSE_ARRAY){
923  enus->state = ENU_YP_ARRAY;
924  } else if(j->st ==YJSON_PARSE_STRUCT){
925  enus->state = ENU_SERVICE;
926  }
927  break;
928  case ENU_YP_ARRAY:
929  if(j->st == YJSON_PARSE_STRUCT){
930  enus->state = ENU_YP_ENTRY;
931  enus->serial = INVALID_HASH_IDX;
933  enus->funcId = INVALID_HASH_IDX;
935  enus->funYdx = -1;
936  memset(enus->advertisedValue,0, sizeof(enus->advertisedValue));
937  }else if(j->st ==YJSON_PARSE_ARRAY){
938  enus->state = ENU_YP_TYPE;
939  }else{
940  NETENUMLOG("what is it %s \n",j->token);
941  }
942  break;
943  case ENU_YP_ENTRY:
944  if(j->st ==YJSON_PARSE_STRUCT){
945  ypUpdateNet(enus);
946  enus->state = ENU_YP_ARRAY;
947  }else if(j->st ==YJSON_PARSE_MEMBNAME){
948  if(YSTRCMP(j->token,"baseType")==0){
949  enus->state = ENU_YP_BASETYPE;
950  } else if(YSTRCMP(j->token,"hardwareId")==0){
951  enus->state = ENU_YP_HARDWAREID;
952  } else if(YSTRCMP(j->token,"logicalName")==0){
953  enus->state = ENU_YP_LOGICALNAME;
954  } else if(YSTRCMP(j->token,"advertisedValue")==0){
956  } else if(YSTRCMP(j->token,"index")==0){
957  enus->state = ENU_YP_INDEX;
958  } else {
959  yJsonSkip(j,1);
960  }
961  }
962  break;
963 
964  case ENU_YP_BASETYPE:
965  NETENUMLOG("set baseType value to %s\n",j->token);
966  enus->funClass = atoi(j->token);
967  enus->state = ENU_YP_ENTRY;
968  break;
969  case ENU_YP_HARDWAREID:
970  point = strchr(j->token,'.');
971  if(!point) break; //to be safe discart this field if we do not found '.'
972  *point++ = '\0';
973  NETENUMLOG("set serial to %s\n",j->token);
974  enus->serial = yHashPutStr(j->token);
975  NETENUMLOG("set functionid to %s\n",point);
976  enus->funcId = yHashPutStr(point);
977  enus->state = ENU_YP_ENTRY;
978  break;
979  case ENU_YP_LOGICALNAME:
980  NETENUMLOG("set function to %s\n",j->token);
981  enus->logicalName = yHashPutStr(j->token);
982  enus->state = ENU_YP_ENTRY;
983  break;
985  NETENUMLOG("set advertised value to %s\n",j->token);
987  enus->state = ENU_YP_ENTRY;
988  break;
989  case ENU_YP_INDEX:
990  NETENUMLOG("set funYdx value to %s\n",j->token);
991  enus->funYdx = atoi(j->token);
992  enus->state = ENU_YP_ENTRY;
993  break;
994  default:
995  return YAPI_IO_ERROR;
996  }
997  return YAPI_SUCCESS;
998 }
999 
1000 // connect to a network hub and do an enumeration
1001 // this function will do TCP IO and will do a timeout if
1002 // the hub is off line.
1003 // USE NO NOT USE THIS FUNCTION BUT yNetHubEnum INSTEAD
1004 static int yNetHubEnumEx(HubSt *hub, ENU_CONTEXT *enus, char *errmsg)
1005 {
1007  u8 buffer[1500];
1008  int res;
1009  const char *request = "GET /api.json \r\n\r\n";// no HTTP/1.1 suffix -> light headers
1010  yJsonRetCode jstate = YJSON_NEED_INPUT;
1011  u64 enumTimeout;
1012  RequestSt *req;
1013 #ifdef DEBUG_YAPI_REQ
1014  int req_count = YREQ_LOG_START("yNetHubEnumEx", hub->name, request, YSTRLEN(request));
1015  u64 start_tm = yapiGetTickCount();
1016 #endif
1017  req = yReqAlloc(hub);
1018  if (YISERR((res = yReqOpen(req, 2 * YIO_DEFAULT_TCP_TIMEOUT, 0, request, YSTRLEN(request), YIO_DEFAULT_TCP_TIMEOUT, NULL, NULL, NULL, NULL, errmsg)))) {
1019  yReqFree(req);
1020  return res;
1021  }
1022  // init yjson parser
1023  memset(&j,0,sizeof(j));
1024  j.st = YJSON_HTTP_START;
1025  enus->state = ENU_HTTP_START;
1026  enumTimeout = yapiGetTickCount() + 10000;
1027  while(jstate == YJSON_NEED_INPUT){
1028  res = yReqSelect(req, 1000, errmsg);
1029  if(YISERR(res)){
1030  break;
1031  }
1032  res = yReqRead(req, buffer, sizeof(buffer));
1033  while(res > 0) {
1034 #ifdef DEBUG_YAPI_REQ
1035  YREQ_LOG_APPEND(req_count, "yNetHubEnumEx", buffer, res, start_tm);
1036 #endif
1037  j.src = (char*)buffer;
1038  j.end = (char*)buffer + res;
1039  // parse all we can on this buffer
1040  jstate=yJsonParse(&j);
1041  while(jstate == YJSON_PARSE_AVAIL){
1042  if(YISERR(yEnuJson(enus,&j))){
1043  jstate = YJSON_FAILED;
1044  break;
1045  }
1046  jstate=yJsonParse(&j);
1047  }
1048  res = yReqRead(req, buffer, sizeof(buffer));
1049  }
1050  if(res <= 0) {
1051  res = yReqIsEof(req, errmsg);
1052  if(YISERR(res)){
1053  // any specific error during select
1054  yReqClose(req);
1055  yReqFree(req);
1056  return res;
1057  }
1058  if(res == 1) {
1059  // connection close before end of result
1060  res = YERR(YAPI_IO_ERROR);
1061  }
1062  if (yapiGetTickCount()>= enumTimeout){
1063  res = YERR(YAPI_TIMEOUT);
1064  }
1065  }
1066  }
1067  yReqClose(req);
1068  yReqFree(req);
1069 
1070  if( res == YAPI_SUCCESS ){
1071  switch(jstate){
1072  case YJSON_NEED_INPUT:
1073  return YERRMSG(YAPI_IO_ERROR,"Remote host has close the connection");
1074  case YJSON_PARSE_AVAIL:
1075  case YJSON_FAILED:
1076  return YERRMSG(YAPI_IO_ERROR,"Invalid json data");
1077  case YJSON_SUCCESS:
1078  break;
1079  }
1080  }
1081 
1082  return YAPI_SUCCESS;
1083 }
1084 
1085 
1086 // helper for yNetHubEnumEx that will trigger TCP connection (and potentially
1087 // timeout) only when it is really needed.
1088 static int yNetHubEnum(HubSt *hub,int forceupdate,char *errmsg)
1089 {
1090  ENU_CONTEXT enus;
1091  int i, res;
1092  yStrRef knownDevices[128];
1093 
1094  //check if the expiration has expired;
1095  if(!forceupdate && hub->devListExpires > yapiGetTickCount()) {
1096  return YAPI_SUCCESS;
1097  }
1098 
1099  // et base url (then entry point)
1100  memset(&enus,0,sizeof(enus));
1101  enus.hub = hub;
1102  enus.knownDevices = knownDevices;
1103  enus.nbKnownDevices = wpGetAllDevUsingHubUrl(hub->url, enus.knownDevices, 128);
1104  if(enus.nbKnownDevices >128){
1105  return YERRMSG(YAPI_IO_ERROR,"too many device on this Net hub");
1106  }
1107 
1108 
1109  if (hub->mandatory) {
1110  // if the hub is mandatory we will raise an error
1111  // and not unregister the connected devices
1112  if (hub->send_ping && hub->state != NET_HUB_ESTABLISHED) {
1113  // the hub send ping notification -> we can rely on helperthread status
1114  if (errmsg) {
1115  YSPRINTF(errmsg, YOCTO_ERRMSG_LEN, "hub %s is not reachable", hub->name);
1116  }
1117  return YAPI_IO_ERROR;
1118  } else {
1119  // the hub does not send ping notification -> we will to a request and potentialy
1120  // get a tcp timeout if the hub is not reachable
1121  res = yNetHubEnumEx(hub, &enus, errmsg);
1122  if (YISERR(res)) {
1123  return res;
1124  }
1125  }
1126  } else {
1127  // if the hub is optional we will not triger an error but
1128  // instead unregister all know device connecte on this hub
1129  if (hub->state == NET_HUB_ESTABLISHED) {
1130  // the hub send ping notification -> we can rely on helperthread status
1131  res = yNetHubEnumEx(hub, &enus, errmsg);
1132  if (YISERR(res)) {
1133  dbglog("error with hub %s : %s",hub->name,errmsg);
1134  }
1135  }
1136  }
1137 
1138  for(i=0; i < enus.nbKnownDevices ; i++){
1139  if (enus.knownDevices[i]!=INVALID_HASH_IDX){
1140  unregisterNetDevice(knownDevices[i]);
1141  }
1142  }
1143  if(hub->state == NET_HUB_ESTABLISHED){
1144  hub->devListExpires = yapiGetTickCount()+10000; // 10s validity when notification are working properly
1145  } else {
1146  hub->devListExpires = yapiGetTickCount()+500;
1147  }
1148  return YAPI_SUCCESS;
1149 }
1150 
1151 
1152 // initialize NetHubSt sctructure. no IO in this function
1153 static HubSt* yapiAllocHub(const char *url,char *errmsg)
1154 {
1155  char *name;
1156  int len;
1157  yHash huburl;
1158  yStrRef user, password;
1159  HubSt* hub;
1160 
1161  huburl = yHashUrl(url, "", 0, errmsg);
1162  if (huburl == INVALID_HASH_IDX) {
1163  return NULL;
1164  }
1165 
1166  hub = yMalloc(sizeof(HubSt));
1167  memset(hub,0,sizeof(HubSt));
1168  memset(hub->devYdxMap, 255, sizeof(hub->devYdxMap));
1169  yInitWakeUpSocket(&hub->wuce);
1170  // compute an hashed url
1171  hub->url = huburl;
1172  len = YSTRLEN(url);
1173  name = (char*) yMalloc(len+1);
1174  memcpy(name,url,len+1);
1175  hub->name = name;
1176  yHashGetUrlPort(huburl, NULL, NULL, &hub->proto, &user, &password);
1177  yFifoInit(&(hub->not_fifo), hub->not_buffer, sizeof(hub->not_buffer));
1179 
1180  if (hub->proto != PROTO_WEBSOCKET) {
1181  if (user != INVALID_HASH_IDX) {
1182  hub->http.s_user = yHashGetStrPtr(user);
1183  }
1184  if (password != INVALID_HASH_IDX) {
1185  hub->http.s_pwd = yHashGetStrPtr(password);
1186  }
1188  } else {
1189  hub->ws.s_next_async_id = 48;
1190  }
1191 #ifdef TRACE_NET_HUB
1192  dbglog("HUB%p: %x->%s allocated \n",hub, hub->url, hub->name);
1193 #endif
1194 
1195  return hub;
1196 }
1197 
1198 static void yapiFreeHub(HubSt *hub)
1199 {
1200 #ifdef TRACE_NET_HUB
1201  dbglog("HUB: %x->%s Deleted \n",hub->url,hub->name);
1202 #endif
1203  yFreeWakeUpSocket(&hub->wuce);
1204  if (hub->proto == !PROTO_WEBSOCKET) {
1205  if (hub->http.s_realm) yFree(hub->http.s_realm);
1206  if (hub->http.s_nonce) yFree(hub->http.s_nonce);
1207  if (hub->http.s_opaque) yFree(hub->http.s_opaque);
1208  if (hub->http.notReq) {
1209  yReqClose(hub->http.notReq);
1210  yReqFree(hub->http.notReq);
1211  }
1212  }
1214  yFifoCleanup(&hub->not_fifo);
1215  if (hub->name) yFree(hub->name);
1216  memset(hub, 0, sizeof(HubSt));
1217  memset(hub->devYdxMap, 255, sizeof(hub->devYdxMap));
1218  hub->url = INVALID_HASH_IDX;
1219  yFree(hub);
1220 }
1221 
1222 
1223 
1224 static void unregisterNetHub(yUrlRef huburl)
1225 {
1226  int i;
1227  u64 timeref;
1228  int nbKnownDevices;
1229  yStrRef knownDevices[128];
1230  char errmsg[YOCTO_ERRMSG_LEN];
1231 
1232 
1233  for(i = 0; i < NBMAX_NET_HUB; i++){
1234  HubSt *hub = yContext->nethub[i];
1235  if(hub && yHashSameHub(hub->url, huburl)) {
1236 #ifdef TRACE_NET_HUB
1237  dbglog("HUB: unregister %x->%s \n",huburl,hub->name);
1238 #endif
1239  hub->state = NET_HUB_TOCLOSE;
1241  yDringWakeUpSocket(&hub->wuce, 0, errmsg);
1242  // wait for the helper thread to stop monitoring these devices
1243  timeref = yapiGetTickCount();
1244  while(yThreadIsRunning(&hub->net_thread) && (yapiGetTickCount() - timeref < YIO_DEFAULT_TCP_TIMEOUT) ) {
1245  yApproximateSleep(10);
1246  }
1247  yThreadKill(&hub->net_thread);
1248  yapiFreeHub(hub);
1249  yContext->nethub[i] = NULL;
1250  break;
1251  }
1252  }
1253 
1254  nbKnownDevices = wpGetAllDevUsingHubUrl(huburl,knownDevices,128);
1255  for(i = 0 ; i < nbKnownDevices; i++) {
1256  if (knownDevices[i]!=INVALID_HASH_IDX){
1257  unregisterNetDevice(knownDevices[i]);
1258  }
1259  }
1260 
1261 }
1262 
1263 
1264 
1265 static void ssdpEntryUpdate(const char *serial, const char *urlToRegister, const char *urlToUnregister)
1266 {
1267  if (!yContext)
1268  // API not yet initialized -> drop everthing
1269  return;
1270  if (urlToRegister){
1271  // still valid entry
1274  yContext->hubDiscoveryCallback(serial, urlToRegister);
1276  }
1277  }
1278 
1279  if (yContext->detecttype & Y_DETECT_NET) {
1280  if (urlToRegister) {
1281  if (urlToUnregister) {
1282  yapiUnregisterHub_internal(urlToUnregister);
1283  }
1284  yapiPreregisterHub_internal(urlToRegister, NULL);
1285  }
1286  }
1287 }
1288 
1289 
1290 static void initializeAllCS(yContextSt *ctx)
1291 {
1292  //initialize enumeration CS
1300 }
1301 
1302 static void deleteAllCS(yContextSt *ctx)
1303 {
1304  //initialize enumeration CS
1312 }
1313 
1314 
1315 /*****************************************************************************
1316  API FUNCTIONS
1317  ****************************************************************************/
1318 #pragma pack(push,1)
1319 typedef union{
1320  u32 raw;
1321  struct{
1322  u8 a;
1323  u8 b;
1324  u8 c;
1325  u8 d;
1326  } bytes;
1327 } test_compile;
1328 #pragma pack(pop)
1329 
1330 
1331 static YRETCODE yapiInitAPI_internal(int detect_type,char *errmsg)
1332 {
1333  test_compile test;
1334  yContextSt *ctx;
1335 #ifdef PERF_API_FUNCTIONS
1336  memset(&yApiPerf,0,sizeof(yApiPerf));
1337 #endif
1338 
1339  if(yContext!=NULL)
1340  return YERRMSG(YAPI_DEVICE_BUSY,"Api already started");
1341 #ifdef __BORLANDC__
1342 #pragma warn - 8066
1343 #pragma warn - 8008
1344 #endif
1345  if (sizeof(u8) != 1) return YERRMSG(YAPI_INVALID_ARGUMENT,"invalid definition of u8");
1346  if (sizeof(s8) != 1) return YERRMSG(YAPI_INVALID_ARGUMENT,"invalid definition of s8");
1347  if (sizeof(u16) != 2) return YERRMSG(YAPI_INVALID_ARGUMENT,"invalid definition of u16");
1348  if (sizeof(u32) != 4) return YERRMSG(YAPI_INVALID_ARGUMENT,"invalid definition of u32");
1349  if (sizeof(u64) != 8) return YERRMSG(YAPI_INVALID_ARGUMENT,"invalid definition of u64");
1350  if (sizeof(s16) != 2) return YERRMSG(YAPI_INVALID_ARGUMENT,"invalid definition of s16");
1351  if (sizeof(s32) != 4) return YERRMSG(YAPI_INVALID_ARGUMENT,"invalid definition of s32");
1352  if (sizeof(s64) != 8) return YERRMSG(YAPI_INVALID_ARGUMENT,"invalid definition of s64");
1353  test.raw = 0xdeadbeef;
1354 
1355  if (test.bytes.a == 0xef && test.bytes.d == 0xde) {
1356  // little endian
1357  if (sizeof(test_compile) != 4) return YERRMSG(YAPI_INVALID_ARGUMENT, "pragma pack is not supported");
1358 #ifdef CPU_BIG_ENDIAN
1359  return YERRMSG(YAPI_INVALID_ARGUMENT, "Invalid endianness. Lib is compiled for big endian but is used on little endian cpu");
1360 #endif
1361  } else {
1362  // big endian
1363  if (sizeof(test_compile) != 4) return YERRMSG(YAPI_INVALID_ARGUMENT, "pragma pack is not supported");
1364 #ifndef CPU_BIG_ENDIAN
1365  return YERRMSG(YAPI_INVALID_ARGUMENT, "Invalid endianness. Lib is compiled for little endian but is used on big endian cpu");
1366 #endif
1367  }
1368 
1369 #ifdef __BORLANDC__
1370 #pragma warn . 8008
1371 #pragma warn . 8066
1372 #endif
1373 
1374  if(atof("1") != 1.0){
1375 #if defined(BUILD_ARMHF)
1376  return YERRMSG(YAPI_INVALID_ARGUMENT,"Invalid arm architecture (try armel binaries)");
1377 #elif defined(BUILD_ARMEL)
1378  return YERRMSG(YAPI_INVALID_ARGUMENT,"Invalid arm architecture (try armhf binaries)");
1379 #else
1380  return YERRMSG(YAPI_INVALID_ARGUMENT,"Invalid architecture");
1381 #endif
1382  }
1383 
1384  //init safe malloc
1385  ySafeMemoryInit(64*1024);
1386 #ifdef DEBUG_CRITICAL_SECTION
1387  yInitDebugCS();
1388 #endif
1389 
1390  ctx=(yContextSt*)yMalloc(sizeof(yContextSt));
1391  yMemset(ctx,0,sizeof(yContextSt));
1392  ctx->detecttype=detect_type;
1393 
1394  //initialize enumeration CS
1395  initializeAllCS(ctx);
1396 
1397  //initialize device pool
1398  ctx->devs = NULL;
1399  ctx->devhdlcount = 1;
1400  if(detect_type & Y_DETECT_USB) {
1401  int res;
1402  if(YISERR(res=yUsbInit(ctx,errmsg))){
1403  deleteAllCS(ctx);
1404  yFree(ctx);
1405  return (YRETCODE)res;
1406  }
1407  }
1408 
1409 
1410  //initialize white/yellow pages support
1411  yHashInit();
1412 
1413  if (YISERR(yTcpInit(errmsg))){
1414  deleteAllCS(ctx);
1415  yFree(ctx);
1416  return YAPI_IO_ERROR;
1417  }
1418 
1420 
1421  if(detect_type & Y_DETECT_NET) {
1422  if (YISERR(ySSDPStart(&ctx->SSDP, ssdpEntryUpdate, errmsg))){
1423  yTcpShutdown();
1425  deleteAllCS(ctx);
1426  yFree(ctx);
1427  return YAPI_IO_ERROR;
1428  }
1429  }
1430  yContext=ctx;
1431 #ifndef YAPI_IN_YDEVICE
1432  yProgInit();
1433 #endif
1434  return YAPI_SUCCESS;
1435 }
1436 
1437 static int yTcpTrafficPending(void);
1438 
1439 
1440 static void yapiFreeAPI_internal(void)
1441 {
1442  u64 timeout = yapiGetTickCount() + 1000000;
1443  char errmsg[YOCTO_ERRMSG_LEN];
1444  int i;
1445 
1446  if(yContext==NULL)
1447  return;
1448 
1449 #ifdef PERF_API_FUNCTIONS
1450  dumpYApiPerf();
1451 #endif
1452 
1453 
1454  while(yapiGetTickCount() < timeout && (yUsbTrafficPending() || yTcpTrafficPending())) {
1455  yapiHandleEvents_internal(errmsg);
1456  yApproximateSleep(50);
1457  }
1458 
1459 
1460 #ifndef YAPI_IN_YDEVICE
1461  yProgFree();
1462 #endif
1467  yUsbFree(yContext,NULL);
1468  }
1469 
1470  ySSDPStop(&yContext->SSDP);
1471  //unregister all Network hub
1472  for(i = 0; i < NBMAX_NET_HUB; i++){
1473  if (yContext->nethub[i]) {
1475  }
1476  }
1477 
1478  yHashFree();
1479  yTcpShutdown();
1481 
1487  yFree(yContext);
1488  ySafeMemoryStop();
1489 #ifdef DEBUG_CRITICAL_SECTION
1490  yFreeDebugCS();
1491 #endif
1492 
1493  yContext=NULL;
1494 }
1495 
1496 
1498 {
1499  char errmsg[YOCTO_ERRMSG_LEN];
1500  if(!yContext) {
1501  yapiInitAPI_internal(0,errmsg);
1502  }
1503  if(yContext) {
1505  yContext->log = logfun;
1507  }
1508 }
1509 
1510 
1512 {
1513  char errmsg[YOCTO_ERRMSG_LEN];
1514  if(!yContext) {
1515  yapiInitAPI_internal(0,errmsg);
1516  }
1517  if(yContext) {
1519  yContext->logDeviceCallback = logCallback;
1521  }
1522 }
1523 
1524 static void yapiStartStopDeviceLogCallback_internal(const char *serial,int start)
1525 {
1526  yStrRef serialref;
1527  int devydx;
1528  serialref = yHashPutStr(serial);
1529  devydx = wpGetDevYdx(serialref);
1530  if (devydx < 0 )
1531  return;
1532  dbglog("activate log %s %d\n", serial, start);
1534  if (start) {
1536  } else {
1538  }
1540  yapiPullDeviceLogEx(devydx);
1541 }
1542 
1544 {
1545  char errmsg[YOCTO_ERRMSG_LEN];
1546  if(!yContext) {
1547  yapiInitAPI_internal(0,errmsg);
1548  }
1549  if(yContext) {
1551  yContext->arrivalCallback = arrivalCallback;
1552  if(arrivalCallback != NULL){
1553  // FIXME: WE SHOULD USE THE hash table to list all known devices
1554 #if 0
1555  // call callback with already detected devices
1557  while(p){
1558  devGetAcces(p,1);
1559  if(p->dstatus == YDEV_WORKING){
1560  yStrRef serialref = yHashPutStr(p->infos.serial);
1561  yContext->arrivalCallback(serialref);
1562  }
1563  devReleaseAcces(p);
1564  p=p->next;
1565  }
1566 #endif
1567  }
1569  }
1570 }
1571 
1572 
1574 {
1575  char errmsg[YOCTO_ERRMSG_LEN];
1576  if(!yContext) {
1577  yapiInitAPI_internal(0,errmsg);
1578  }
1579  if(yContext) {
1581  yContext->removalCallback = removalCallback;
1583  }
1584 }
1585 
1586 
1588 {
1589  char errmsg[YOCTO_ERRMSG_LEN];
1590  if(!yContext) {
1591  yapiInitAPI_internal(0,errmsg);
1592  }
1593  if(yContext) {
1594  yContext->changeCallback = changeCallback;
1595  }
1596 }
1597 
1598 
1600 {
1601  char errmsg[YOCTO_ERRMSG_LEN];
1602  if(!yContext) {
1603  yapiInitAPI_internal(0,errmsg);
1604  }
1605  if(yContext) {
1606  yContext->functionCallback = updateCallback;
1607  }
1608 }
1609 
1611 {
1612  char errmsg[YOCTO_ERRMSG_LEN];
1613  if(!yContext) {
1614  yapiInitAPI_internal(0,errmsg);
1615  }
1616  if(yContext) {
1617  yContext->timedReportCallback = timedReportCallback;
1618  }
1619 }
1620 
1621 
1622 
1623 #ifdef DEBUG_NET_NOTIFICATION
1624 static void dumpNotif(const char *buffer)
1625 {
1626  FILE *f;
1627  printf("%s",buffer);
1628  YASSERT(YFOPEN(&f,"c:\\tmp\\api_not.txt","ab")==0);
1629  fwrite(buffer,1,YSTRLEN(buffer),f);
1630  fclose(f);
1631 }
1632 #endif
1633 
1634 
1635 static void wpUpdateTCP(HubSt *hub, const char *serial, const char *name, u8 beacon)
1636 {
1637  #define LOCALURL_LEN 64
1638  int status;
1639  char devUrlBuf[LOCALURL_LEN];
1640  yStrRef serialref;
1641  yStrRef lnameref;
1642  yUrlRef devurl;
1643  int devydx;
1644 
1645  serialref = yHashPutStr(serial);
1646  devydx = wpGetDevYdx(serialref);
1647 
1648  if (devydx < 0) {
1649  // drop notification until we have register the device with
1650  // a real enumeration
1651  return;
1652  }
1653 
1654  if (hub->serial != serialref) {
1655  // Insert device into white pages
1656  YSTRCPY(devUrlBuf, LOCALURL_LEN, "/bySerial/");
1657  YSTRCAT(devUrlBuf, LOCALURL_LEN, serial);
1658  YSTRCAT(devUrlBuf, LOCALURL_LEN, "/api");
1659  devurl = yHashUrlFromRef(hub->url, devUrlBuf);
1660  } else {
1661  devurl = hub->url;
1662  }
1663  lnameref = yHashPutStr(name);
1664  status = wpRegister(-1, serialref, lnameref, INVALID_HASH_IDX, 0, devurl, beacon);
1665  if (status == 0) {
1666  return; // no change
1667  }
1669  // Forward high-level notification to API user
1670  if(yContext->changeCallback){
1672  yContext->changeCallback(serialref);
1674  }
1675 }
1676 
1678 {
1679  u16 pos;
1680  u16 end,size;
1681  char buffer[128];
1682  char *p;
1683  u8 pkttype = 0,devydx,funydx,funclass;
1684  char *serial = NULL,*name,*funcid,*children;
1685  char value[YOCTO_PUBVAL_LEN];
1686  u8 report[18];
1687  char netstop=NOTIFY_NETPKT_STOP;
1688  char escapechar = 27;
1689 #ifdef DEBUG_NET_NOTIFICATION
1690  u32 abspos = hub->notifAbsPos;
1691  char Dbuffer[1024];
1692  u8 throwbuf[1024];
1693  u16 tmp;
1694 #endif
1695 
1696  // search for start of notification
1697  size = yFifoGetUsed(&(hub->not_fifo));
1698  while(size >= NOTIFY_NETPKT_START_LEN) {
1699  yPeekFifo(&(hub->not_fifo), &pkttype, 1, 0);
1700  if(pkttype != NOTIFY_NETPKT_STOP) break;
1701  // drop newline and loop
1702  yPopFifo(&(hub->not_fifo),NULL,1);
1703  // note: keep-alive packets don't count in the notification channel position
1704  size--;
1705  }
1706  if(size < NOTIFY_NETPKT_START_LEN) {
1707  return 0;
1708  }
1709  // make sure we have a full notification
1710  end = ySeekFifo(&(hub->not_fifo), (u8*) &netstop, 1, 0, 0, 0);
1711  if(end == 0xffff){
1712  if (yFifoGetFree(&(hub->not_fifo)) == 0) {
1713  dbglog("Too many invalid notifications, clearing buffer\n");
1714  yFifoEmpty((&(hub->not_fifo)));
1715  return 1;
1716  }
1717  return 0;
1718  }
1719  // make sure we have a full notification
1720  if (0xffff != ySeekFifo(&(hub->not_fifo), (u8*) &escapechar, 1, 0, end, 0)) {
1721  // drop notification that contain esc char
1722  yPopFifo(&(hub->not_fifo), NULL, end + 1);
1723  return 1;
1724  }
1725  // handle short funcvalydx notifications
1726  if(pkttype >= NOTIFY_NETPKT_FLUSHV2YDX && pkttype <= NOTIFY_NETPKT_TIMEAVGYDX) {
1727  memset(value, 0, YOCTO_PUBVAL_LEN);
1728  if (end + 1 > (u16) sizeof(buffer)){
1729  dbglog("Drop invalid short notification (too long :%d)\n", end + 1);
1730  hub->notifAbsPos += end + 1;
1731  return 1;
1732  }
1733  yPopFifo(&(hub->not_fifo),(u8*) buffer,end+1);
1734  hub->notifAbsPos += end+1;
1735  p = buffer+1;
1736  devydx = (*p++) - 'A';
1737  funydx = (*p++) - '0';
1738  if(funydx & 64) { // high bit of devydx is on second character
1739  funydx -= 64;
1740  devydx += 128;
1741  }
1742  pos = 0;
1743  switch (pkttype) {
1745  while(*p != 0 && *p != NOTIFY_NETPKT_STOP && pos < YOCTO_PUBVAL_LEN-1) {
1746  value[pos++] = *p++;
1747  }
1748  value[pos] = 0;
1749 #ifdef DEBUG_NET_NOTIFICATION
1750  YSPRINTF(Dbuffer,512,"FuncVYDX >devYdx=%d funYdx=%d val=%s (%d)\n",
1751  devydx,funydx,value,abspos);
1752  dumpNotif(Dbuffer);
1753 #endif
1754  // Map hub-specific devydx to our devydx
1755  devydx = hub->devYdxMap[devydx];
1756  if(devydx < MAX_YDX_PER_HUB) {
1757  Notification_funydx funInfo;
1758  funInfo.raw = funydx;
1759  ypUpdateYdx(devydx,funInfo,value);
1760  }
1761  break;
1763  // Map hub-specific devydx to our devydx
1764  devydx = hub->devYdxMap[devydx];
1765  if(devydx < MAX_YDX_PER_HUB) {
1769 #ifdef DEBUG_NET_NOTIFICATION
1770  dbglog("notify device log for devydx %d\n", devydx);
1771 #endif
1772  }
1774  }
1775  break;
1779  // Map hub-specific devydx to our devydx
1780  devydx = hub->devYdxMap[devydx];
1781  if(devydx >= MAX_YDX_PER_HUB) break;
1782 
1783  report[pos++] = (pkttype == NOTIFY_NETPKT_TIMEVALYDX ? 0 :
1784  (pkttype == NOTIFY_NETPKT_TIMEAVGYDX ? 1 : 2));
1785  while (isxdigit((u8)p[0]) && isxdigit((u8)p[1]) && pos < sizeof(report)) {
1786  int hi_nib = (p[0] <= '9' ? p[0]-'0' : 10+(p[0]&0x4f)-'A');
1787  int lo_nib = (p[1] <= '9' ? p[1]-'0' : 10+(p[1]&0x4f)-'A');
1788  report[pos++] = hi_nib * 16 + lo_nib;
1789  p += 2;
1790  }
1791  #ifdef DEBUG_NET_NOTIFICATION
1792  YSPRINTF(Dbuffer,512,"%s >devYdx=%d funYdx=%d (%d)\n",
1793  (pkttype == NOTIFY_NETPKT_TIMEVALYDX ? "TimeValR" : "TimeAvgR"),
1794  devydx,funydx,abspos);
1795  dumpNotif(Dbuffer);
1796  #endif
1797  if(funydx == 15) {
1798  u32 t = report[1] + 0x100u * report[2] + 0x10000u * report[3] + 0x1000000u * report[4];
1800  yContext->generic_infos[devydx].deviceTime = (double)t + report[5] / 250.0;
1802  } else {
1803  Notification_funydx funInfo;
1804  YAPI_FUNCTION fundesc;
1805  double deviceTime;
1807  deviceTime = yContext->generic_infos[devydx].deviceTime;
1809  funInfo.raw = funydx;
1810  ypRegisterByYdx(devydx, funInfo, NULL, &fundesc);
1811  yFunctionTimedUpdate(fundesc, deviceTime, report, pos);
1812  }
1813  break;
1815  while(*p != 0 && *p != NOTIFY_NETPKT_STOP && pos < YOCTO_PUBVAL_LEN-1) {
1816  value[pos++] = *p++;
1817  }
1818  value[pos] = 0;
1819  // Map hub-specific devydx to our devydx
1820  devydx = hub->devYdxMap[devydx];
1821  if(devydx < MAX_YDX_PER_HUB) {
1822  Notification_funydx funInfo;
1823  unsigned char value8bit[YOCTO_PUBVAL_LEN];
1824  memset(value8bit, 0, YOCTO_PUBVAL_LEN);
1825  funInfo.raw = funydx;
1826  if(decodeNetFuncValV2((u8*)value, &funInfo, (char*)value8bit) >= 0) {
1827 #ifdef DEBUG_NET_NOTIFICATION
1828  if(!funInfo.v2.typeV2) {
1829  YSPRINTF(Dbuffer,512,"FuncV2YDX >devYdx=%d funYdx=%d val=%s (%d)\n",devydx,funydx,value8bit,abspos);
1830  } else {
1831  YSPRINTF(Dbuffer,512,"FuncV2YDX >devYdx=%d funYdx=%d val=%d:%02x.%02x.%02x.%02x.%02x.%02x (%d)\n",
1832  devydx, funInfo.v2.funydx, funInfo.v2.typeV2,
1833  value8bit[0],value8bit[1],value8bit[2],value8bit[3],value8bit[4],value8bit[5],abspos);
1834  }
1835  dumpNotif(Dbuffer);
1836 #endif
1837  ypUpdateYdx(devydx,funInfo,(char *)value8bit);
1838  }
1839  }
1840  break;
1842  // To be implemented later
1843  break;
1844  default:
1845  break;
1846  }
1847  return 1;
1848  }
1849 
1850  // make sure packet is a valid notification
1851  pos = ySeekFifo(&(hub->not_fifo), (u8*) (NOTIFY_NETPKT_START), NOTIFY_NETPKT_START_LEN, 0, end, 0);
1852  if(pos != 0) {
1853  // does not start with signature, drop everything until stop marker
1854 #ifdef DEBUG_NET_NOTIFICATION
1855  memset(throwbuf, 0, sizeof(throwbuf));
1856  tmp = (end > 50 ? 50 : end);
1857  yPopFifo(&(hub->not_fifo),throwbuf,tmp);
1858  yPopFifo(&(hub->not_fifo),NULL,end+1-tmp);
1859  Dbuffer[1023]=0;
1860  YSPRINTF(Dbuffer,512,"throw %d / %d [%s]\n",
1861  end,pos,throwbuf);
1862  dumpNotif(Dbuffer);
1863 #else
1864  yPopFifo(&(hub->not_fifo),NULL,end+1);
1865 #endif
1866  hub->notifAbsPos += end+1;
1867  return 0;
1868  }
1869 
1870  // full packet at start of fifo
1871  size = end - NOTIFY_NETPKT_START_LEN;
1873  yPopFifo(&(hub->not_fifo),NULL,NOTIFY_NETPKT_START_LEN);
1874  yPopFifo(&(hub->not_fifo),(u8*) buffer,size+1);
1875  buffer[size]=0;
1876  pkttype = *buffer;
1877  p = buffer+1;
1878  if(pkttype == NOTIFY_NETPKT_NOT_SYNC) {
1879  int testPing;
1880 #ifdef DEBUG_NET_NOTIFICATION
1881  YSPRINTF(Dbuffer,512,"Sync from %d to %s\n",
1882  hub->notifAbsPos, p);
1883  dumpNotif(Dbuffer);
1884 #endif
1885  hub->notifAbsPos = atoi(p);
1886  //look if we have a \n just after the sync notification
1887  // if yes this mean that the hub will send some ping notification
1888  testPing = ySeekFifo(&(hub->not_fifo), (u8*) &netstop, 1, 0, 1, 0);
1889  if(testPing == 0){
1890 #ifdef DEBUG_NET_NOTIFICATION
1891  YSPRINTF(Dbuffer,1024,"HUB: %X->%s will send ping notification\n",hub->url,hub->name);
1892  dumpNotif(Dbuffer);
1893 #endif
1894  hub->send_ping = 1;
1895  }
1896  return 1;
1897  }
1898  hub->notifAbsPos += size+1+NOTIFY_NETPKT_START_LEN;
1899  if(pkttype != NOTIFY_NETPKT_FUNCVALYDX) {
1900  serial = p;
1901  p = strchr(serial,NOTIFY_NETPKT_SEP);
1902  if(p==NULL) {
1903 #ifdef DEBUG_NET_NOTIFICATION
1904  YSPRINTF(Dbuffer,512,"no serialFOR %s\n",buffer);
1905  dumpNotif(Dbuffer);
1906 #endif
1907  return 0;
1908  }
1909  *p++ = 0;
1910  }
1911 
1912 
1913  switch(pkttype){
1914  case NOTIFY_NETPKT_NAME:
1915  name = p;
1916  p = strchr(name,NOTIFY_NETPKT_SEP);
1917  if(p==NULL){
1918 #ifdef DEBUG_NET_NOTIFICATION
1919  dbglog("drop: invalid new name (%X)\n",pkttype);
1920 #endif
1921  return 1;
1922  }
1923  *p++ = 0;
1924 #ifdef DEBUG_NET_NOTIFICATION
1925  dbglog("NOTIFY_PKT_NAME %s : new name is \"%s\" beacon %x\n",serial,name ,*p);
1926  YSPRINTF(Dbuffer,512,"NAME >%s name=%s beacon=%c (%d)\n",serial,name,*p,abspos);
1927  dumpNotif(Dbuffer);
1928 #endif
1929  wpUpdateTCP(hub,serial,name,(*p== '1' ? 1:0));
1930  break;
1932  funcid = p;
1933  p = strchr(funcid,NOTIFY_NETPKT_SEP);
1934  if(p==NULL){
1935 #ifdef DEBUG_NET_NOTIFICATION
1936  dbglog("drop: invalid funcid (%X:%s)\n",pkttype,serial);
1937 #endif
1938  return 1;
1939  }
1940  *p++ = 0;
1941  name = p;
1942 #ifdef DEBUG_NET_NOTIFICATION
1943  dbglog("NOTIFY_PKT_FUNCNAME %s : funcid is \"%s\" name \"%s\"\n",serial,funcid,name);
1944  YSPRINTF(Dbuffer,512,"FuncNAME >%s funcid=%s funcname=%s (%d)\n",
1945  serial,funcid,name,abspos);
1946  dumpNotif(Dbuffer);
1947 #endif
1948  ypUpdateUSB(serial,funcid,name,-1,-1,NULL);
1949  break;
1950  case NOTIFY_NETPKT_FUNCVAL:
1951  funcid = p;
1952  p = strchr(funcid,NOTIFY_NETPKT_SEP);
1953  if(p==NULL){
1954 #ifdef DEBUG_NET_NOTIFICATION
1955  dbglog("drop: invalid funcid (%X)\n",pkttype);
1956 #endif
1957  return 1;
1958  }
1959  *p++ = 0;
1960  memset(value,0,YOCTO_PUBVAL_LEN);
1961  memcpy(value,p,YSTRLEN(p));
1962 #ifdef DEBUG_NET_NOTIFICATION
1963  //dbglog("NOTIFY_PKT_FUNCVAL %s : funcid is \"%s\" value \"%s\"\n",serial,funcid,value);
1964  YSPRINTF(Dbuffer,512,"FuncVAL >%s funcid=%s val=%s (%d)\n",
1965  serial,funcid,value,abspos);
1966  dumpNotif(Dbuffer);
1967 #endif
1968  ypUpdateUSB(serial,funcid,NULL,-1,-1,value);
1969  break;
1971  funcid = p;
1972  p = strchr(funcid,NOTIFY_NETPKT_SEP);
1973  if(p==NULL){
1974 #ifdef DEBUG_NET_NOTIFICATION
1975  dbglog("drop: invalid funcid (%X:%s)\n",pkttype,serial);
1976 #endif
1977  return 1;
1978  }
1979  *p++ = 0;
1980  name = p;
1981  p = strchr(name,NOTIFY_NETPKT_SEP);
1982  if(p==NULL){
1983 #ifdef DEBUG_NET_NOTIFICATION
1984  dbglog("drop: invalid funcname (%X:%s)\n",pkttype,serial);
1985 #endif
1986  return 1;
1987  }
1988  *p++ = 0;
1989  funydx = atoi(p);
1990  p = strchr(p,NOTIFY_NETPKT_SEP);
1991  if(p==NULL || p[1] < '0'){
1992  funclass = YOCTO_AKA_YFUNCTION;
1993  } else {
1994  funclass = p[1]-'0';
1995  }
1996 #ifdef DEBUG_NET_NOTIFICATION
1997  YSPRINTF(Dbuffer,512,"FuncNYDX >%s funcid=%s funcname=%s funYdx=%d (%d)\n",
1998  serial,funcid,name,funydx,abspos);
1999  dumpNotif(Dbuffer);
2000 #endif
2001  ypUpdateUSB(serial,funcid,name,funclass,funydx,NULL);
2002  break;
2003  case NOTIFY_NETPKT_CHILD:
2004  children = p;
2005  p = strchr(children,NOTIFY_NETPKT_SEP);
2006  if(p==NULL){
2007 #ifdef DEBUG_NET_NOTIFICATION
2008  dbglog("drop: invalid children notification (%X)\n",pkttype);
2009 #endif
2010  return 1;
2011  }
2012  *p++ = 0;
2013 #ifdef DEBUG_NET_NOTIFICATION
2014  dbglog("NOTIFY_PKT_CHILDREN %s : new children is \"%s\" plug %x\n",serial,children ,*p);
2015  YSPRINTF(Dbuffer,512,"CHILD >%s childserial=%s on-off=%c (%d)\n",
2016  serial, children,*p,abspos);
2017  dumpNotif(Dbuffer);
2018 #endif
2019  if ( *p == '0') {
2020  unregisterNetDevice(yHashPutStr(children));
2021  }
2022  break;
2023  case NOTIFY_NETPKT_LOG:
2024 #ifdef DEBUG_NET_NOTIFICATION
2025  dbglog("NOTIFY_NETPKT_LOG %s\n", serial);
2026 #endif
2027  {
2028  yStrRef serialref = yHashPutStr(serial);
2029  int devydx = wpGetDevYdx(serialref);
2030  if (devydx >= 0) {
2034 #ifdef DEBUG_NET_NOTIFICATION
2035  dbglog("notify device log for %s (%d)\n", serial,devydx);
2036 #endif
2037  }
2039  }
2040  }
2041  break;
2042  default:
2043 #ifdef DEBUG_NET_NOTIFICATION
2044  dbglog("drop: invalid pkttype (%X)\n",pkttype);
2045  dumpNotif("drop: invalid pkttype\n");
2046 #endif
2047  break;
2048 
2049  }
2050  return 1;
2051 }
2052 
2053 static int yTcpTrafficPending(void)
2054 {
2055  int i;
2056  HubSt *hub;
2057 
2058  for (i = 0; i < NBMAX_NET_HUB; i++) {
2059  hub = yContext->nethub[i];
2060  if (hub == NULL || hub->url == INVALID_HASH_IDX)
2061  continue;
2062  if (yReqHasPending(hub)) {
2063  return 1;
2064  }
2065  }
2066  return 0;
2067 }
2068 
2069 static void* yhelper_thread(void* ctx)
2070 {
2071  int i,towatch;
2072  u8 buffer[512];
2073  yThread *thread=(yThread*)ctx;
2074  char errmsg[YOCTO_ERRMSG_LEN];
2075  HubSt *hub = (HubSt*) thread->ctx;
2076  RequestSt *req, *selectlist[1+ALLOC_YDX_PER_HUB];
2077  u32 toread;
2078  int res;
2079  int first_notification_connection=1;
2080 #ifdef DEBUG_NET_NOTIFICATION
2081  char Dbuffer[1024];
2082 #endif
2083 
2084 
2085 
2086  yThreadSignalStart(thread);
2087  while (!yThreadMustEnd(thread)) {
2088  // Handle async connections as well in this thread
2089  for (i = 0; i < ALLOC_YDX_PER_HUB; i++) {
2090  int devydx = hub->devYdxMap[i];
2091  if (devydx != 0xff){
2092  yapiPullDeviceLogEx(devydx);
2093  }
2094  }
2095  towatch=0;
2096  if (hub->state == NET_HUB_ESTABLISHED || hub->state == NET_HUB_TRYING) {
2097  selectlist[towatch] = hub->http.notReq;
2098  towatch++;
2099  } else if(hub->state == NET_HUB_TOCLOSE) {
2100  yReqClose(hub->http.notReq);
2101  hub->state = NET_HUB_CLOSED;
2102  } else if (hub->state == NET_HUB_DISCONNECTED) {
2103  u64 now;
2104  if(hub->http.notReq == NULL) {
2105  hub->http.notReq = (RequestSt*) yMalloc(sizeof(RequestSt));
2106  hub->http.notReq = yReqAlloc(hub);
2107  }
2108  now = yapiGetTickCount();
2109  if ( (u64)( now - hub->lastAttempt ) > hub->attemptDelay) {
2110  char request[256];
2111 #ifdef TRACE_NET_HUB
2112  dbglog("TRACE(%X->%s): try to open notification socket at %d\n",hub->url,hub->name, hub->notifAbsPos);
2113 #endif
2114  // reset fifo
2115  yFifoEmpty(&(hub->not_fifo));
2116  if (first_notification_connection) {
2117  YSPRINTF(request, 256, "GET /not.byn HTTP/1.1\r\n\r\n");
2118  } else {
2119  YSPRINTF(request, 256, "GET /not.byn?abs=%u HTTP/1.1\r\n\r\n", hub->notifAbsPos);
2120  }
2121  res = yReqOpen(hub->http.notReq, 2 * YIO_DEFAULT_TCP_TIMEOUT, 0, request, YSTRLEN(request), 0, NULL, NULL, NULL, NULL, errmsg);
2122  if (YISERR(res)) {
2123  hub->attemptDelay = 500 << hub->retryCount;
2124  if(hub->attemptDelay > 8000)
2125  hub->attemptDelay = 8000;
2126  hub->lastAttempt = yapiGetTickCount();
2127  hub->retryCount++;
2129  hub->errcode = ySetErr(res, hub->errmsg, errmsg, NULL, 0);
2131 
2132 #ifdef TRACE_NET_HUB
2133  dbglog("TRACE(%X->%s): unable to open notification socket(%s)\n",hub->url,hub->name,errmsg);
2134  dbglog("TRACE(%X->%s): retry in %dms (%d retries)\n",hub->url,hub->name,hub->attemptDelay,hub->retryCount);
2135 #endif
2136  } else {
2137 #ifdef TRACE_NET_HUB
2138  dbglog("TRACE(%X->%s): notification socket open\n",hub->url,hub->name);
2139 #endif
2140 #ifdef DEBUG_NET_NOTIFICATION
2141  YSPRINTF(Dbuffer,1024,"HUB: %X->%s started\n",hub->url,hub->name);
2142  dumpNotif(Dbuffer);
2143 #endif
2144  hub->state = NET_HUB_TRYING;
2145  hub->retryCount=0;
2146  hub->attemptDelay = 500;
2148  hub->send_ping = 0;
2149  selectlist[towatch++] = hub->http.notReq;
2150  first_notification_connection = 0;
2151  }
2152  }
2153  }
2154 
2155  // Handle async connections as well in this thread
2156  for (i=0; i < ALLOC_YDX_PER_HUB; i++) {
2157  req = yContext->tcpreq[i];
2158  if(req == NULL || req->hub != hub){
2159  continue;
2160  }
2161  if(yReqIsAsync(req)) {
2162  selectlist[towatch++] = req;
2163  }
2164  }
2165 
2166  if(YISERR(yReqMultiSelect(selectlist, towatch, 1000, &hub->wuce, errmsg))){
2167  dbglog("yTcpMultiSelectReq failed (%s)\n",errmsg);
2168  yApproximateSleep(1000);
2169  } else {
2170  for (i = 0; i < towatch; i++) {
2171  req = selectlist[i];
2172  if(req == hub->http.notReq) {
2173  toread = yFifoGetFree(&hub->not_fifo);
2174  while(toread > 0) {
2175  if(toread >= sizeof(buffer)) toread = sizeof(buffer)-1;
2176  res = yReqRead(req, buffer, toread);
2177  if(res > 0) {
2178  buffer[res]=0;
2179 #if 0 //def DEBUG_NET_NOTIFICATION
2180  YSPRINTF(Dbuffer,1024,"HUB: %X->%s push %d [\n%s\n]\n",hub->url,hub->name,res,buffer);
2181  dumpNotif(Dbuffer);
2182 #endif
2183  yPushFifo(&(hub->not_fifo), (u8*)buffer, res);
2184  if(hub->state == NET_HUB_TRYING) {
2185  int eoh = ySeekFifo(&(hub->not_fifo), (u8 *)"\r\n\r\n", 4, 0, 0, 0);
2186  if(eoh != 0xffff) {
2187  if(eoh >= 12) {
2188  yPopFifo(&(hub->not_fifo), (u8 *)buffer, 12);
2189  yPopFifo(&(hub->not_fifo), NULL, eoh+4-12);
2190  if(!memcmp((u8 *)buffer, (u8 *)"HTTP/1.1 200", 12)) {
2191  hub->state = NET_HUB_ESTABLISHED;
2192  }
2193  }
2194  if(hub->state != NET_HUB_ESTABLISHED) {
2195  // invalid header received, give up
2196  char hubname[YOCTO_HOSTNAME_NAME]="";
2197  hub->state = NET_HUB_TOCLOSE;
2198  yHashGetUrlPort(hub->url, hubname, NULL, NULL, NULL, NULL);
2199  dbglog("Network hub %s cannot provide notifications", hubname);
2200  }
2201  }
2202  }
2203  if(hub->state == NET_HUB_ESTABLISHED) {
2204  while(handleNetNotification(hub));
2205  }
2207  } else {
2208  if (hub->send_ping && ( (u64)(yapiGetTickCount() - hub->http.lastTraffic)) > NET_HUB_NOT_CONNECTION_TIMEOUT){
2209 #ifdef TRACE_NET_HUB
2210 
2211  dbglog("network hub %s(%x) didn't respond for too long (%d)\n", hub->name, hub->url, res);
2212 #endif
2213  yReqClose(req);
2214  hub->state = NET_HUB_DISCONNECTED;
2215  }
2216  // nothing more to be read, exit loop
2217  break;
2218  }
2219  toread = yFifoGetFree(&hub->not_fifo);
2220  }
2221  res = yReqIsEof(req, errmsg);
2222  if (res != 0) {
2223  // error or remote close
2224  yReqClose(req);
2225  hub->state = NET_HUB_DISCONNECTED;
2226  if (res == 1) {
2227  // remote close
2228  YERRMSG(YAPI_IO_ERROR, "Connection closed by remote host");
2229  dbglog("Disconnected from network hub %s (%s)\n", hub->name, errmsg);
2230  } else {
2231  //error
2232  hub->attemptDelay = 500 << hub->retryCount;
2233  if (hub->attemptDelay > 8000)
2234  hub->attemptDelay = 8000;
2235  hub->lastAttempt = yapiGetTickCount();
2236  hub->retryCount++;
2238  hub->errcode = ySetErr(res, hub->errmsg, errmsg, NULL, 0);
2240  }
2241 #ifdef DEBUG_NET_NOTIFICATION
2242  YSPRINTF(Dbuffer, 1024, "Network hub %X->%s has closed the connection for notification\n", hub->url, hub->name);
2243  dumpNotif(Dbuffer);
2244 #endif
2245  }
2246  } else if (yReqIsAsync(req)) {
2247  res = yReqIsEof(req, errmsg);
2248  if(res != 0) {
2249  yReqClose(req);
2250  }
2251  }
2252  }
2253  }
2254  }
2255 
2256  if (hub->state == NET_HUB_TOCLOSE) {
2257  yReqClose(hub->http.notReq);
2258  hub->state = NET_HUB_CLOSED;
2259  }
2260 
2261  yThreadSignalEnd(thread);
2262  return NULL;
2263 }
2264 
2265 
2267 {
2268  if(!yContext)
2269  return YERR(YAPI_NOT_INITIALIZED);
2271  return YAPI_SUCCESS;
2272 }
2273 
2274 
2276 {
2277  if(!yContext)
2278  return YERR(YAPI_NOT_INITIALIZED);
2280  return YAPI_SUCCESS;
2281 }
2282 
2283 
2285 {
2286  if(!yContext)
2287  return YERR(YAPI_NOT_INITIALIZED);
2289  return YAPI_SUCCESS;
2290 }
2291 
2292 
2293 
2295 {
2296  if(!yContext)
2297  return YERR(YAPI_NOT_INITIALIZED);
2299  return YAPI_SUCCESS;
2300 }
2301 
2302 
2303 static YRETCODE yapiRegisterHubEx(const char* url, int checkacces, char* errmsg)
2304 {
2305  int i;
2306  int res;
2307 
2308  if (!yContext) {
2309  YPROPERR(yapiInitAPI_internal(0,errmsg));
2310  }
2311 
2312  if (YSTRICMP(url,"usb") == 0) {
2313  if (!(yContext->detecttype & Y_DETECT_USB)) {
2315  res = yUsbInit(yContext, errmsg);
2316  if (!YISERR(res)) {
2318  }
2320  YPROPERR(res);
2321  }
2322  if (checkacces) {
2324  res = yUSBUpdateDeviceList(errmsg);
2326  return res;
2327  }
2328  } else if (YSTRICMP(url,"net") == 0) {
2329  if (!(yContext->detecttype & Y_DETECT_NET)) {
2332  res = ySSDPStart(&yContext->SSDP, ssdpEntryUpdate, errmsg);
2334  YPROPERR(res);
2335  }
2336  if (checkacces) {
2337  res = yapiUpdateDeviceList_internal(1, errmsg);
2338  return res;
2339  }
2340  } else {
2341  HubSt *hubst = NULL;
2342  int firstfree;
2343  void* (*thead_handler)(void *);
2344 
2345  hubst = yapiAllocHub(url, errmsg);
2346  if (hubst == NULL) {
2347  return YAPI_INVALID_ARGUMENT;
2348  }
2349  if (checkacces) {
2350  hubst->mandatory = 1;
2351  }
2352  //look if we allready know this
2354  firstfree = NBMAX_NET_HUB;
2355  for (i = 0; i < NBMAX_NET_HUB; i++) {
2356  if (yContext->nethub[i] && yHashSameHub(yContext->nethub[i]->url, hubst->url))
2357  break;
2358  if (firstfree == NBMAX_NET_HUB && yContext->nethub[i] == NULL) {
2359  firstfree = i;
2360  }
2361  }
2362 
2363 
2364  if (i >= NBMAX_NET_HUB && firstfree < NBMAX_NET_HUB) {
2365  i = firstfree;
2366  // save mapping attributed from first access
2367 #ifdef TRACE_NET_HUB
2368  dbglog("HUB: register %x->%s \n", hubst->url, hubst->name);
2369 #endif
2370  yContext->nethub[i] = hubst;
2371  if (YISERR(res = yStartWakeUpSocket(&yContext->nethub[i]->wuce, errmsg))) {
2373  return (YRETCODE)res;
2374  }
2375  if (hubst->proto == PROTO_WEBSOCKET) {
2376  thead_handler = ws_thread;
2377  } else {
2378  thead_handler = yhelper_thread;
2379  }
2380  //yThreadCreate will not create a new thread if there is already one running
2381  if (yThreadCreate(&yContext->nethub[i]->net_thread, thead_handler, (void*)yContext->nethub[i]) < 0) {
2383  return YERRMSG(YAPI_IO_ERROR, "Unable to start helper thread");
2384  }
2385  yDringWakeUpSocket(&yContext->nethub[i]->wuce, 1, errmsg);
2386  }
2388  if (i == NBMAX_NET_HUB) {
2389  yapiFreeHub(hubst);
2390  return YERRMSG(YAPI_INVALID_ARGUMENT, "Too many network hub registered");
2391  }
2392 
2393  if (checkacces) {
2394  // ensure the thread has been able to connect to the hub
2395  u64 timeout = yapiGetTickCount() + YIO_DEFAULT_TCP_TIMEOUT;
2396  while (hubst->state != NET_HUB_ESTABLISHED && hubst->state != NET_HUB_CLOSED && hubst->retryCount==0 && timeout > yapiGetTickCount()) {
2397  yapiSleep(100, errmsg);
2398  }
2399  if (hubst->state != NET_HUB_ESTABLISHED) {
2400  yEnterCriticalSection(&hubst->access);
2402  yLeaveCriticalSection(&hubst->access);
2403  if (!YISERR(res)) {
2404  return YERRMSG(YAPI_IO_ERROR, "hub not ready");
2405  }
2406  unregisterNetHub(hubst->url);
2407  return res;
2408  }
2410  res = yNetHubEnum(hubst, 1, errmsg);
2412  if (YISERR(res)) {
2414  } else if (hubst->proto != PROTO_WEBSOCKET) {
2415  // for HTTP test admin pass if the hub require it
2416  if (hubst->writeProtected && hubst->http.s_user && strcmp(hubst->http.s_user, "admin") == 0) {
2417  YIOHDL iohdl;
2418  const char* request = "GET /api/module/serial?serial=&. ";
2419  char *reply = NULL;
2420  int replysize = 0;
2421  int tmpres = yapiHTTPRequestSyncStartEx_internal(&iohdl, 0, yHashGetStrPtr(hubst->serial) , request, YSTRLEN(request), &reply, &replysize, NULL, NULL, errmsg);
2422  if (tmpres == YAPI_UNAUTHORIZED) {
2423  return tmpres;
2424  }
2425  if (tmpres == YAPI_SUCCESS) {
2426  yapiHTTPRequestSyncDone_internal(&iohdl, errmsg);
2427  }
2428  }
2429  }
2430 
2431  return res;
2432  }
2433 
2434  }
2435  return YAPI_SUCCESS;
2436 }
2437 
2438 
2439 static int pingURLOnhub(HubSt *hubst, const char *request, int mstimeout, char *errmsg)
2440 {
2442  u8 buffer[1500];
2443  int res;
2444  yJsonRetCode jstate = YJSON_NEED_INPUT;
2445  u64 globalTimeout;
2446  RequestSt *req;
2447 
2448  globalTimeout = yapiGetTickCount() + mstimeout;
2449 
2450  req = yReqAlloc(hubst);
2451  if (YISERR((res = yReqOpen(req, 2 * YIO_DEFAULT_TCP_TIMEOUT, 0, request, YSTRLEN(request), mstimeout, NULL, NULL, NULL, NULL, errmsg)))) {
2452  yReqFree(req);
2453  return res;
2454  }
2455  // init yjson parser
2456  memset(&j, 0, sizeof(j));
2457  j.st = YJSON_HTTP_START;
2458  while (jstate == YJSON_NEED_INPUT) {
2459  res = yReqSelect(req, 500, errmsg);
2460  if (YISERR(res)) {
2461  break;
2462  }
2463  res = yReqRead(req, buffer, sizeof(buffer));
2464  while (res > 0) {
2465  j.src = (char*) buffer;
2466  j.end = (char*) buffer + res;
2467  // parse all we can on this buffer
2468  jstate = yJsonParse(&j);
2469  while (jstate == YJSON_PARSE_AVAIL) {
2470  jstate = yJsonParse(&j);
2471  }
2472  res = yReqRead(req, buffer, sizeof(buffer));
2473  }
2474  if (res <= 0) {
2475  res = yReqIsEof(req, errmsg);
2476  if (YISERR(res)) {
2477  // any specific error during select
2478  yReqClose(req);
2479  yReqFree(req);
2480  return res;
2481  }
2482  if (res == 1 && jstate == YJSON_NEED_INPUT) {
2483  // connection close before end of result
2484  res = YERR(YAPI_IO_ERROR);
2485  }
2486  if (yapiGetTickCount() >= globalTimeout) {
2487  res = YERR(YAPI_TIMEOUT);
2488  }
2489  }
2490  }
2491  yReqClose(req);
2492  yReqFree(req);
2493 
2494  if (res == YAPI_SUCCESS) {
2495  switch (jstate) {
2496  case YJSON_NEED_INPUT:
2497  return YERRMSG(YAPI_IO_ERROR,"Remote host has close the connection");
2498  case YJSON_PARSE_AVAIL:
2499  case YJSON_FAILED:
2500  return YERRMSG(YAPI_IO_ERROR,"Invalid json data");
2501  case YJSON_SUCCESS:
2502  break;
2503  }
2504  }
2505  return res;
2506 }
2507 
2508 static YRETCODE yapiTestHub_internal(const char *url, int mstimeout, char *errmsg)
2509 {
2510  int freeApi = 0;
2511  int res;
2512 
2513  if(!yContext) {
2514  YPROPERR(yapiInitAPI_internal(0,errmsg));
2515  freeApi = 1;
2516  }
2517 
2518  if(YSTRICMP(url, "usb") == 0) {
2519  res = YAPI_SUCCESS;
2520  } else if(YSTRICMP(url, "net") == 0) {
2521  res = YAPI_SUCCESS;
2522  }else{
2523  HubSt *hubst = yapiAllocHub(url, errmsg);
2524  if (hubst){
2525 #ifdef TRACE_NET_HUB
2526  dbglog("HUB: test %x->%s \n", hubst->url, hubst->name);
2527 #endif
2528  if (hubst->proto == PROTO_WEBSOCKET) {
2529  u64 timeout;
2530  if (YISERR(res = yStartWakeUpSocket(&hubst->wuce, errmsg))) {
2531  yapiFreeHub(hubst);
2532  return (YRETCODE)res;
2533  }
2534  //yThreadCreate will not create a new thread if there is already one running
2535  if (yThreadCreate(&hubst->net_thread, ws_thread, (void*)hubst) < 0) {
2536  yapiFreeHub(hubst);
2537  return YERRMSG(YAPI_IO_ERROR, "Unable to start helper thread");
2538  }
2539  yDringWakeUpSocket(&hubst->wuce, 1, errmsg);
2540 
2541  // ensure the thread has been able to connect to the hub
2542  timeout = yapiGetTickCount() + mstimeout;
2543  while (hubst->state != NET_HUB_ESTABLISHED && hubst->state != NET_HUB_CLOSED && hubst->retryCount == 0 && timeout > yapiGetTickCount()) {
2544  yapiSleep(10, errmsg);
2545  }
2546  if (hubst->state != NET_HUB_ESTABLISHED) {
2547  yEnterCriticalSection(&hubst->access);
2548  res = YERRMSGSILENT(hubst->errcode, hubst->errmsg);
2549  yLeaveCriticalSection(&hubst->access);
2550  if (!YISERR(res)) {
2551  res = YERRMSG(YAPI_IO_ERROR, "hub not ready");
2552  }
2553  }
2554  if (!YISERR(res)) {
2555  res = pingURLOnhub(hubst, "GET /api/module/firmwareRelease.json \r\n\r\n", (int)(timeout - yapiGetTickCount()), errmsg);
2556  }
2557  hubst->state = NET_HUB_TOCLOSE;
2558  yThreadRequestEnd(&hubst->net_thread);
2559  yDringWakeUpSocket(&hubst->wuce, 0, errmsg);
2560  // wait for the helper thread to stop monitoring these devices
2561  yThreadKill(&hubst->net_thread);
2562  } else {
2563  res = pingURLOnhub(hubst, "GET /api/module/firmwareRelease.json \r\n\r\n", mstimeout, errmsg);
2564  }
2565  yapiFreeHub(hubst);
2566  } else{
2567  return YAPI_IO_ERROR;
2568  }
2569  }
2570  if (freeApi) {
2572  }
2573  return res;
2574 }
2575 
2576 
2577 static YRETCODE yapiRegisterHub_internal(const char *url, char *errmsg)
2578 {
2579  YRETCODE res;
2580  res = yapiRegisterHubEx(url,1, errmsg);
2581  return res;
2582 }
2583 
2584 static YRETCODE yapiPreregisterHub_internal(const char *url, char *errmsg)
2585 {
2586  YRETCODE res;
2587  res = yapiRegisterHubEx(url,0, errmsg);
2588  return res;
2589 }
2590 
2591 static void yapiUnregisterHub_internal(const char *url)
2592 {
2593  yUrlRef huburl;
2594 
2595  if(!yContext) {
2596  return;
2597  }
2598  if (YSTRICMP(url,"usb")==0) {
2601  yUsbFree(yContext,NULL);
2603  }
2604  }else if(YSTRICMP(url,"net")==0){
2607  }
2608  }else{
2609  // compute an hashed url
2610  huburl = yHashUrl(url,"",1,NULL);
2611  if(huburl == INVALID_HASH_IDX){
2612  return;
2613  }
2614  //look if we allready know this
2616  unregisterNetHub(huburl);
2618  }
2619 }
2620 
2621 
2622 static YRETCODE yapiUpdateDeviceList_internal(u32 forceupdate, char *errmsg)
2623 {
2624  int i;
2625  YRETCODE err =YAPI_SUCCESS;
2626  char suberr[YOCTO_ERRMSG_LEN];
2627 
2628  if(yContext==NULL)
2629  return YERR(YAPI_NOT_INITIALIZED);
2630 
2631  if(forceupdate) {
2633  } else {
2634  // if we do not force an update
2636  return YAPI_SUCCESS;
2637  }
2638  }
2640  err = yUSBUpdateDeviceList(errmsg);
2641  }
2642 
2643  for(i = 0; i < NBMAX_NET_HUB; i++){
2644  if(yContext->nethub[i]){
2645  int subres;
2646  if (YISERR(subres = yNetHubEnum(yContext->nethub[i], forceupdate, suberr)) && err == YAPI_SUCCESS) {
2647  //keep first generated error
2648  char buffer[YOCTO_HOSTNAME_NAME]="";
2649  u16 port;
2650  err = (YRETCODE) subres;
2651  yHashGetUrlPort(yContext->nethub[i]->url, buffer, &port, NULL, NULL, NULL);
2652  if(errmsg) {
2653  YSPRINTF(errmsg,YOCTO_ERRMSG_LEN,"Enumeration failed for %s:%d (%s)",buffer,port,suberr);
2654  }
2655  }
2656  }
2657  }
2659 
2660  return err;
2661 }
2662 
2663 
2665 {
2666  if(!yContext)
2667  return YERR(YAPI_NOT_INITIALIZED);
2668  // we need only one thread to handle the event at a time
2670  YRETCODE res = (YRETCODE) yUsbIdle();
2672  return res;
2673  }
2674  return YAPI_SUCCESS;
2675 }
2676 
2677 u64 test_pkt=0;
2679 
2680 static YRETCODE yapiSleep_internal(int ms_duration, char *errmsg)
2681 {
2682  u64 now, timeout;
2683  YRETCODE err = YAPI_SUCCESS;
2684 
2685 
2686  if(!yContext)
2687  return YERR(YAPI_NOT_INITIALIZED);
2688 
2689  timeout = yapiGetTickCount() + ms_duration;
2690  do {
2691  if(err == YAPI_SUCCESS) {
2692  err = yapiHandleEvents_internal(errmsg);
2693  }
2694  now =yapiGetTickCount();
2695  // todo: we may want to use a samller timeout
2696  if (now < timeout) {
2697  if (yWaitForEvent(&yContext->exitSleepEvent, (int) (timeout - now)))
2698  test_pkt++; //just for testing
2699  else
2700  test_tout++;
2701  }
2702  } while(yapiGetTickCount() < timeout);
2703 
2704  return err;
2705 }
2706 
2707 #ifdef WINDOWS_API
2708 static int tickUseHiRes = -1;
2709 static u64 tickOffset = 0;
2710 static LARGE_INTEGER tickFrequency;
2711 static LARGE_INTEGER tickStart;
2712 #endif
2714 {
2715  u64 res;
2716 
2717 #ifdef WINDOWS_API
2718  LARGE_INTEGER performanceCounter;
2719 
2720  if(tickUseHiRes < 0){
2721  if (QueryPerformanceFrequency(&tickFrequency)){
2722  tickUseHiRes = 1;
2723  tickOffset = (u64)time(NULL) * 1000u;
2724  QueryPerformanceCounter(&tickStart);
2725  } else {
2726  tickUseHiRes = 0;
2727  tickOffset = (u64)time(NULL) * 1000u - GetTickCount();
2728  }
2729  // make sure the offset is always > 0
2730  if((s64)tickOffset <= 0) tickOffset = 1;
2731  }
2732  if(tickUseHiRes>0) {
2733  QueryPerformanceCounter(&performanceCounter);
2734  performanceCounter.QuadPart -= tickStart.QuadPart;
2735  // we add +1 because it is not nice to start with zero
2736  res = performanceCounter.QuadPart * 1000 / tickFrequency.QuadPart + tickOffset;
2737  } else {
2738  res = GetTickCount() + tickOffset;
2739  }
2740 #else
2741  //get the current number of microseconds since January 1st 1970
2742  struct timeval tim;
2743  gettimeofday(&tim, NULL);
2744  res = (u64)tim.tv_sec * 1000 + (tim.tv_usec / 1000);
2745 #endif
2746 
2747  return res;
2748 }
2749 
2750 u32 yapiGetCNonce(u32 nc)
2751 {
2752  HASH_SUM ctx;
2753  u32 md5[4];
2754 
2755 #ifdef WINDOWS_API
2756  LARGE_INTEGER performanceCounter;
2757 
2758  if(tickUseHiRes>0) {
2759  QueryPerformanceCounter(&performanceCounter);
2760  } else {
2761  performanceCounter.QuadPart = GetTickCount();
2762  }
2763  MD5Initialize(&ctx);
2764  MD5AddData(&ctx, (u8 *)&performanceCounter, sizeof(performanceCounter));
2765 #else
2766  //get the current number of microseconds since January 1st 1970
2767  struct timeval tim;
2768 
2769  gettimeofday(&tim, NULL);
2770  MD5Initialize(&ctx);
2771  MD5AddData(&ctx, (u8 *)&tim, sizeof(tim));
2772 #endif
2773  MD5AddData(&ctx, (u8 *)&nc, sizeof(nc));
2774  MD5Calculate(&ctx, (u8 *)md5);
2775 
2776  return md5[1];
2777 }
2778 
2779 static int yapiCheckLogicalName_internal(const char *name)
2780 {
2781  char c;
2782 
2783  if(!name) return 0;
2784  if(!*name) return 1;
2785  if(strlen(name) > 19) return 0;
2786  while((c = *name++) != 0) {
2787  if(c < '-') return 0;
2788  if(c > '-' && c < '0') return 0;
2789  if(c > '9' && c < 'A') return 0;
2790  if(c > 'Z' && c < '_') return 0;
2791  if(c > '_' && c < 'a') return 0;
2792  if(c > 'z') return 0;
2793  }
2794  return 1;
2795 }
2796 
2797 
2798 static u16 yapiGetAPIVersion_internal(const char **version, const char **apidate)
2799 {
2800  if(version)
2802  if(apidate)
2803  *apidate = YOCTO_API_BUILD_DATE;
2804 
2805  return YOCTO_API_VERSION_BCD;
2806 }
2807 
2808 static void yapiSetTraceFile_internal(const char *file)
2809 {
2810  if(file!=NULL){
2811  memset(ytracefile,0,TRACEFILE_NAMELEN);
2813  }else{
2814  ytracefile[0]=0;
2815  }
2816 }
2817 
2818 
2819 static YAPI_DEVICE yapiGetDevice_internal(const char *device_str, char *errmsg)
2820 {
2821  char hostname[HASH_BUF_SIZE], c;
2822  int i;
2823  YAPI_DEVICE res;
2824 
2825  if(!yContext)
2826  return YERR(YAPI_NOT_INITIALIZED);
2827 
2828  if(!strncmp(device_str, "http://", 7)) {
2829  for(i = 0; i < HASH_BUF_SIZE-1; i++) {
2830  c = device_str[7+i];
2831  if(!c || c == '/') break;
2832  hostname[i] = c;
2833  }
2834  res = wpSearchByUrl(hostname, device_str+7+i);
2835  } else {
2836  res = wpSearch(device_str);
2837  }
2838  if(res == -1) {
2839  return YERR(YAPI_DEVICE_NOT_FOUND);
2840  }
2841 
2842  return res;
2843 }
2844 
2845 
2846 static int yapiGetAllDevices_internal(YAPI_DEVICE *buffer, int maxsize, int *neededsize, char *errmsg)
2847 {
2848  int maxdev,nbreturned;
2849  yBlkHdl devhdl;
2850  YAPI_DEVICE devdescr;
2851 
2852  if(!yContext)
2853  return YERR(YAPI_NOT_INITIALIZED);
2854 
2855  if(buffer==NULL && neededsize==NULL){
2856  return YERR(YAPI_INVALID_ARGUMENT);
2857  }
2858 
2859  nbreturned = 0;
2860  if(buffer) {
2861  // This function walks through the white pages without taking the mutex globally
2862  // it is only reasonably safe because wpGetAttribute properly handles dangerous devhdl.
2863  // (same principle as used by HTTPSendRec for the REST API)
2864  maxdev = 0;
2865  for(devhdl = yWpListHead; devhdl != INVALID_BLK_HDL; devhdl = yBlkListSeek(devhdl, 1)) {
2866  devdescr = wpGetAttribute(devhdl, Y_WP_SERIALNUMBER);
2867  if(devdescr < 0) continue;
2868  maxdev++;
2869  if(maxsize >= (int)sizeof(YAPI_DEVICE)) {
2870  maxsize -= sizeof(YAPI_DEVICE);
2871  *buffer++ = devdescr;
2872  nbreturned++;
2873  }
2874  }
2875  if(neededsize) *neededsize = sizeof(YAPI_DEVICE) * maxdev;
2876  } else {
2877  if(neededsize) *neededsize = sizeof(YAPI_DEVICE) * wpEntryCount();
2878  }
2879 
2880  return nbreturned;
2881 }
2882 
2883 
2884 static YRETCODE yapiGetDeviceInfo_internal(YAPI_DEVICE devdesc, yDeviceSt *infos, char *errmsg)
2885 {
2886  YUSBDEV devhdl;
2887 
2888  if(!yContext)
2889  return YERR(YAPI_NOT_INITIALIZED);
2890 
2891  if(devdesc < 0 || infos == NULL){
2892  return YERR(YAPI_INVALID_ARGUMENT);
2893  }
2894 
2895  yHashGetStr(devdesc & 0xffff, infos->serial, YOCTO_SERIAL_LEN);
2896  devhdl = findDevHdlFromStr(infos->serial);
2897  if(devhdl != INVALID_YHANDLE) {
2898  // local device, get all information straight from the source
2899  devHdlInfo(devhdl, infos);
2900  } else {
2901  // not a local device, get available information from white pages
2902  infos->vendorid = 0x24e0;
2903  infos->devrelease = 0;
2904  infos->nbinbterfaces = 1;
2905  memcpy((u8 *)infos->manufacturer, (u8 *)"Yoctopuce", 10);
2906  memset(infos->firmware, 0, YOCTO_FIRMWARE_LEN);
2907  if(wpGetDeviceInfo(devdesc, &infos->deviceid, infos->productname, infos->serial, infos->logicalname, &infos->beacon) < 0){
2908  return YERR(YAPI_DEVICE_NOT_FOUND);
2909  }
2910  }
2911 
2912  return YAPI_SUCCESS;
2913 }
2914 
2915 static YRETCODE yapiGetDevicePath_internal(YAPI_DEVICE devdesc, char *rootdevice, char *request, int requestsize, int *neededsize, char *errmsg)
2916 {
2917  YRETCODE res;
2918 
2919  if(!yContext)
2920  return YERR(YAPI_NOT_INITIALIZED);
2921  if(rootdevice==NULL && request==NULL && neededsize==NULL) {
2922  return YERR(YAPI_INVALID_ARGUMENT);
2923  }
2924  res = (YRETCODE) wpGetDeviceUrl(devdesc, rootdevice, request, requestsize, neededsize);
2925  if(neededsize) *neededsize += 4;
2926  if(res < 0) {
2927  return YERR(YAPI_DEVICE_NOT_FOUND);
2928  }
2929  return res;
2930 }
2931 
2932 
2933 static YRETCODE yapiGetDevicePathEx_internal(const char *serial, char *rootdevice, char *request, int requestsize, int *neededsize, char *errmsg)
2934 {
2935  YAPI_DEVICE devdescr;
2936  yUrlRef url;
2937  char host[YOCTO_HOSTNAME_NAME];
2938  char buffer[512];
2939  u16 port;
2940  yAsbUrlProto proto;
2941 
2942  if (!yContext)
2943  return YERR(YAPI_NOT_INITIALIZED);
2944  if (rootdevice==NULL && request==NULL && neededsize==NULL) {
2945  return YERR(YAPI_INVALID_ARGUMENT);
2946  }
2947  devdescr = wpSearch(serial);
2948  if (YISERR(devdescr)) {
2949  return YERR(YAPI_DEVICE_NOT_FOUND);
2950  }
2951  url = wpGetDeviceUrlRef(devdescr);
2952  switch (yHashGetUrlPort(url, host, &port, &proto, NULL, NULL)) {
2953  case USB_URL:
2954  if (rootdevice) {
2955  *rootdevice = 0;
2956  }
2957  if (request && requestsize > 4) {
2958  YSTRCPY(request, requestsize, "usb");
2959  }
2960  if (*neededsize){
2961  *neededsize = 4;
2962  }
2963  break;
2964  default:
2965  wpGetDeviceUrl(devdescr, rootdevice, buffer, 512, neededsize);
2966  if (request) {
2967 
2968  int len = YSPRINTF(request, requestsize, "%s://%s:%d%s", proto == PROTO_WEBSOCKET ? "ws" : "http", host, port, buffer);
2969  *neededsize = len + 1;
2970  }
2971  if (rootdevice && YSTRCMP(rootdevice, serial) == 0) {
2972  *rootdevice = 0;
2973  }
2974  }
2975  return YAPI_SUCCESS;
2976 }
2977 
2978 
2979 static YAPI_FUNCTION yapiGetFunction_internal(const char *class_str, const char *function_str, char *errmsg)
2980 {
2981  YAPI_FUNCTION res;
2982 
2983  if(!yContext)
2984  return YERR(YAPI_NOT_INITIALIZED);
2985 
2986  res = ypSearch(class_str, function_str);
2987  if(res < 0) {
2988  if(res == -2) {
2989  return YERRMSG(YAPI_DEVICE_NOT_FOUND, "No function of that class");
2990  }
2991  return YERR(YAPI_DEVICE_NOT_FOUND);
2992  }
2993  return res;
2994 }
2995 
2996 static int yapiGetFunctionsByClass_internal(const char *class_str, YAPI_FUNCTION prevfundesc,
2997  YAPI_FUNCTION *buffer,int maxsize,int *neededsize,char *errmsg)
2998 {
2999  int res;
3000  if(!yContext)
3001  return YERR(YAPI_NOT_INITIALIZED);
3002  if(buffer==NULL && neededsize==NULL){
3003  return YERR(YAPI_INVALID_ARGUMENT);
3004  }
3005 
3006  res = ypGetFunctions(class_str, -1, prevfundesc, buffer, maxsize, neededsize);
3007  if(res < 0) {
3008  return YERR(YAPI_DEVICE_NOT_FOUND); // prevfundesc is invalid or has been unplugged, restart enum
3009  }
3010 
3011  return res;
3012 }
3013 
3015  YAPI_FUNCTION *buffer,int maxsize,int *neededsize,char *errmsg)
3016 {
3017  int res;
3018  if(!yContext)
3019  return YERR(YAPI_NOT_INITIALIZED);
3020  if(buffer==NULL && neededsize==NULL){
3021  return YERR(YAPI_INVALID_ARGUMENT);
3022  }
3023  res = ypGetFunctions(NULL, devdesc, prevfundesc, buffer, maxsize, neededsize);
3024  if(res < 0) {
3025  return YERR(YAPI_DEVICE_NOT_FOUND); // prevfundesc is invalid or has been unplugged, restart enum
3026  }
3027  return res;
3028 }
3029 
3030 
3031 static YRETCODE yapiGetFunctionInfoEx_internal(YAPI_FUNCTION fundesc, YAPI_DEVICE *devdesc, char *serial, char *funcId, char *baseType, char *funcName, char *funcVal, char *errmsg)
3032 {
3033  if(!yContext)
3034  return YERR(YAPI_NOT_INITIALIZED);
3035 
3036  if(ypGetFunctionInfo(fundesc, serial, funcId, baseType, funcName, funcVal) < 0) {
3037  return YERR(YAPI_DEVICE_NOT_FOUND);
3038  }
3039  if(devdesc)
3040  *devdesc = fundesc & 0xffff;
3041 
3042  return YAPI_SUCCESS;
3043 }
3044 
3045 
3046 static int yapiRequestOpenUSB(YIOHDL_internal *iohdl, HubSt *hub, YAPI_DEVICE dev, const char *request, int reqlen, u64 unused_timeout, yapiRequestAsyncCallback callback, void *context, char *errmsg)
3047 {
3048  char buffer[512];
3049  YRETCODE res;
3050  int firsttime = 1;
3051  u64 timeout;
3052  int count = 0;
3053 
3054  yHashGetStr(dev & 0xffff, buffer, YOCTO_SERIAL_LEN);
3056  do {
3057  count++;
3058  res = (YRETCODE)yUsbOpen(iohdl, buffer, errmsg);
3059  if (res != YAPI_DEVICE_BUSY) break;
3060  yapiHandleEvents_internal(errmsg);
3061  if (firsttime) {
3062  //yApproximateSleep(1);
3063  firsttime = 0;
3064  }
3065  } while (yapiGetTickCount() < timeout);
3066 
3067  if (res != YAPI_SUCCESS) {
3068  return res;
3069  }
3070  if (reqlen >= 10 && reqlen <= (int) sizeof(buffer) && !memcmp(request + reqlen - 7, "&. \r\n\r\n", 7)) {
3071  memcpy(buffer, request, reqlen - 7);
3072  memcpy(buffer + reqlen - 7, " \r\n\r\n", 5);
3073  reqlen -= 2;
3074  request = buffer;
3075  }
3076  res = (YRETCODE)yUsbWrite(iohdl, request, reqlen, errmsg);
3077  if (YISERR(res)) {
3078  yUsbClose(iohdl, errmsg);
3079  return res;
3080  }
3081  if (callback) {
3082  res = (YRETCODE)yUsbSetIOAsync(iohdl, callback, context, errmsg);
3083  if (YISERR(res)) {
3084  yUsbClose(iohdl, errmsg);
3085  return res;
3086  }
3087  }
3088  return res;
3089 }
3090 
3091 
3092 static int yapiRequestOpenHTTP(YIOHDL_internal *iohdl, HubSt *hub, YAPI_DEVICE dev, const char *request, int reqlen, int wait_for_start, u64 mstimeout, yapiRequestAsyncCallback callback, void *context, char *errmsg)
3093 {
3094  YRETCODE res;
3095  int devydx;
3096  RequestSt *tcpreq;
3097 
3098  devydx = wpGetDevYdx((yStrRef)dev);
3099  if (devydx < 0) {
3100  return YERR(YAPI_DEVICE_NOT_FOUND);
3101  }
3103  tcpreq = yContext->tcpreq[devydx];
3104  if (tcpreq == NULL) {
3105  tcpreq = yReqAlloc(hub);
3106  yContext->tcpreq[devydx] = tcpreq;
3107  }
3109  if (callback) {
3110  if (tcpreq->hub->writeProtected) {
3111  // no need to take the critical section tcpreq->hub->http.authAccess since we only read user an pass
3112  if (!tcpreq->hub->http.s_user || strcmp(tcpreq->hub->http.s_user, "admin") != 0) {
3113  return YERRMSG(YAPI_UNAUTHORIZED, "Access denied: admin credentials required");
3114  }
3115  }
3116  }
3117  if ((tcpreq->hub->send_ping || !tcpreq->hub->mandatory) && tcpreq->hub->state != NET_HUB_ESTABLISHED) {
3118  if (errmsg) {
3119  YSPRINTF(errmsg, YOCTO_ERRMSG_LEN, "hub %s is not reachable", tcpreq->hub->name);
3120  }
3121  return YAPI_IO_ERROR;
3122  }
3123 
3124  res = (YRETCODE)yReqOpen(tcpreq, wait_for_start, 0, request, reqlen, mstimeout, callback, context, NULL, NULL, errmsg);
3125  if (res != YAPI_SUCCESS) {
3126  return res;
3127  }
3128 
3129  if (callback) {
3130  res = (YRETCODE)yDringWakeUpSocket(&tcpreq->hub->wuce, 2, errmsg);
3131  if (res != YAPI_SUCCESS) {
3132  return res;
3133  }
3134  }
3135  iohdl->tcpreqidx = devydx;
3136  iohdl->type = YIO_TCP;
3137  return YAPI_SUCCESS;
3138 }
3139 
3140 static int yapiRequestOpenWS(YIOHDL_internal *iohdl, HubSt *hub, YAPI_DEVICE dev, int tcpchan, const char *request, int reqlen, u64 mstimeout, yapiRequestAsyncCallback callback, void *context, RequestProgress progress_cb, void *progress_ctx, char *errmsg)
3141 {
3142  YRETCODE res;
3143  int devydx;
3144  RequestSt *req;
3145 
3146  devydx = wpGetDevYdx((yStrRef)dev);
3147  if (devydx < 0) {
3148  return YERR(YAPI_DEVICE_NOT_FOUND);
3149  }
3150 
3151  //dbglog("yapiRequestOpenWS on %p %s\n", hub, callback ? "ASYNC": "");
3152  if (callback) {
3153  if (hub->writeProtected && !hub->rw_access) {
3154  return YERRMSG(YAPI_UNAUTHORIZED, "Access denied: admin credentials required");
3155  }
3156  }
3157  req = yReqAlloc(hub);
3158  if ((req->hub->send_ping || !req->hub->mandatory) && req->hub->state != NET_HUB_ESTABLISHED) {
3159  if (errmsg) {
3160  YSPRINTF(errmsg, YOCTO_ERRMSG_LEN, "hub %s is not reachable", req->hub->name);
3161  }
3162  return YAPI_IO_ERROR;
3163  }
3164 
3165  if (req->hub->state != NET_HUB_ESTABLISHED) {
3166  if (YISERR(req->hub->errcode)) {
3168  res = YERRMSG(req->hub->errcode, req->hub->errmsg);
3170  return res;
3171  }
3172  if (errmsg) {
3173  YSPRINTF(errmsg, YOCTO_ERRMSG_LEN, "hub %s is not ready", req->hub->name);
3174  }
3175  return YERRMSG(YAPI_TIMEOUT, "hub is not ready");
3176  }
3177 
3178  res = (YRETCODE)yReqOpen(req, 2 * YIO_DEFAULT_TCP_TIMEOUT, tcpchan, request, reqlen, mstimeout, callback, context, progress_cb, progress_ctx, errmsg);
3179  if (res != YAPI_SUCCESS) {
3180  return res;
3181  }
3182 
3183  iohdl->ws = req;
3184  iohdl->type = YIO_WS;
3185  return YAPI_SUCCESS;
3186 }
3187 
3188 
3189 YRETCODE yapiRequestOpen(YIOHDL_internal *iohdl, int tcpchan, const char *device, const char *request, int reqlen, yapiRequestAsyncCallback callback, void *context, yapiRequestProgressCallback progress_cb, void *progress_ctx, char *errmsg)
3190 {
3191  YAPI_DEVICE dev;
3192  char buffer[512];
3193  yUrlRef url;
3194  yAsbUrlProto proto;
3195  int i, len;
3196  u64 mstimeout = YIO_DEFAULT_TCP_TIMEOUT;
3197  HubSt *hub = NULL;
3198 
3199  if(!yContext) {
3200  return YERR(YAPI_NOT_INITIALIZED);
3201  }
3202 
3203  dev = wpSearch(device);
3204  if(dev == -1) {
3205  return YERR(YAPI_DEVICE_NOT_FOUND);
3206  }
3207 
3208  YASSERT(iohdl != NULL);
3209  memset(iohdl, 0, sizeof(YIOHDL_internal));
3210  // compute request timeout
3211  len = (reqlen < YOCTO_SERIAL_LEN + 32 ? reqlen : YOCTO_SERIAL_LEN + 32);
3212  if (memcmp(request, "GET ", 4) == 0) {
3213  if (ymemfind((u8*)request + 4, len, (u8*)"/testcb.txt", 11) >= 0) {
3214  mstimeout = YIO_1_MINUTE_TCP_TIMEOUT;
3215  } else if (ymemfind((u8*)request + 4, len, (u8*)"/rxmsg.json", 11) >= 0) {
3216  mstimeout = YIO_1_MINUTE_TCP_TIMEOUT;
3217  } else if (ymemfind((u8*)request + 4, len, (u8*)"/files.json", 11) >= 0) {
3218  mstimeout = YIO_1_MINUTE_TCP_TIMEOUT;
3219  } else if (ymemfind((u8*)request + 4, len, (u8*)"/flash.json", 11) >= 0) {
3220  mstimeout = YIO_10_MINUTES_TCP_TIMEOUT;
3221  }
3222  } else {
3223  if (ymemfind((u8*)request + 4, len, (u8*)"/upload.html", 12) >= 0) {
3224  //fixme: use 1 minute timeout for WS
3225  mstimeout = YIO_10_MINUTES_TCP_TIMEOUT;
3226  }
3227  }
3228 
3229  // dispatch request on correct hub (or pseudo usb HUB)
3230  url = wpGetDeviceUrlRef(dev);
3231  switch(yHashGetUrlPort(url, buffer, NULL, &proto, NULL, NULL)) {
3232  case USB_URL:
3233  return yapiRequestOpenUSB(iohdl, NULL, dev, request, reqlen, mstimeout, callback, context, errmsg);
3234  default:
3235  for (i = 0; i < NBMAX_NET_HUB; i++) {
3236  if (yContext->nethub[i] && yHashSameHub(yContext->nethub[i]->url, url)) {
3237  hub = yContext->nethub[i];
3238  break;
3239  }
3240  }
3241  if (hub == NULL) {
3242  return YERR(YAPI_DEVICE_NOT_FOUND);
3243  }
3244  if (proto == PROTO_WEBSOCKET) {
3245  return yapiRequestOpenWS(iohdl, hub, dev, tcpchan, request, reqlen, mstimeout, callback, context, progress_cb, progress_ctx, errmsg);
3246  } else {
3247  return yapiRequestOpenHTTP(iohdl, hub, dev, request, reqlen, 2 * YIO_DEFAULT_TCP_TIMEOUT, mstimeout, callback, context, errmsg);
3248  }
3249  }
3250 }
3251 
3252 static int yapiRequestWaitEndUSB(YIOHDL_internal *iohdl, char **reply, int *replysize, char *errmsg)
3253 {
3254  u64 timeout;
3255  yPrivDeviceSt *p;
3256  int buffpos = 0;
3257  int res;
3258 
3259 
3261  p = findDevFromIOHdl(iohdl);
3262  if (p == NULL) {
3263  return YERR(YAPI_DEVICE_NOT_FOUND);
3264  }
3265  if (p->replybuf == NULL) {
3266  p->replybufsize = 2048;
3267  p->replybuf = (char*)yMalloc(p->replybufsize);
3268  }
3269  while ((res = (YRETCODE)yUsbEOF(iohdl, errmsg)) == 0) {
3270  if (yapiGetTickCount() > timeout) {
3271  yUsbClose(iohdl, NULL);
3272  return YERRMSG(YAPI_TIMEOUT, "Timeout during device request");
3273  }
3274  if (buffpos + 256 > p->replybufsize) {
3275  char *newbuff;
3276  p->replybufsize <<= 1;
3277  newbuff = (char*)yMalloc(p->replybufsize);
3278  memcpy(newbuff, p->replybuf, buffpos);
3279  yFree(p->replybuf);
3280  p->replybuf = newbuff;
3281  }
3282  res = (YRETCODE)yUsbReadBlock(iohdl, p->replybuf + buffpos, p->replybufsize - buffpos, timeout, errmsg);
3283  if (YISERR(res)) {
3284  yUsbClose(iohdl, NULL);
3285  return res;
3286  } else if (res > 0) {
3288  }
3289  buffpos += res;
3290  }
3291  *reply = p->replybuf;
3292  *replysize = buffpos;
3293  return res;
3294 }
3295 
3296 
3297 static int yapiRequestWaitEndHTTP(YIOHDL_internal *iohdl, char **reply, int *replysize, char *errmsg)
3298 {
3299  int res;
3300  RequestSt *tcpreq = yContext->tcpreq[iohdl->tcpreqidx];
3301 
3302  res = (YRETCODE)yReqIsEof(tcpreq, errmsg);
3303  while (res == 0) {
3304  res = (YRETCODE)yReqSelect(tcpreq, 1000, errmsg);
3305  if (YISERR(res)) {
3306  yReqClose(tcpreq);
3307  return res;
3308  }
3309  res = (YRETCODE)yReqIsEof(tcpreq, errmsg);
3310  }
3311  if (YISERR(res) && res != YAPI_NO_MORE_DATA) {
3312  yReqClose(tcpreq);
3313  return res;
3314  }
3315  *replysize = yReqGet(tcpreq, (u8**)reply);
3316  return YAPI_SUCCESS;
3317 }
3318 
3319 
3320 
3321 
3322 static int yapiRequestWaitEndWS(YIOHDL_internal *iohdl, char **reply, int *replysize, char *errmsg)
3323 {
3324  int res;
3325  RequestSt *tcpreq = iohdl->ws;
3326 
3327  res = (YRETCODE)yReqIsEof(tcpreq, errmsg);
3328  while (res == 0) {
3329  res = (YRETCODE)yReqSelect(tcpreq, 1000, errmsg);
3330  if (YISERR(res)) {
3331  yReqClose(tcpreq);
3332  return res;
3333  }
3334  res = (YRETCODE)yReqIsEof(tcpreq, errmsg);
3335  }
3336  if (YISERR(res) && res != YAPI_NO_MORE_DATA) {
3337  yReqClose(tcpreq);
3338  return res;
3339  }
3340  *replysize = yReqGet(tcpreq, (u8**)reply);
3341  return YAPI_SUCCESS;
3342 
3343 
3344 }
3345 
3346 
3347 
3348 YRETCODE yapiHTTPRequestSyncStartEx_internal(YIOHDL *iohdl, int tcpchan, const char *device, const char *request, int requestsize, char **reply, int *replysize, yapiRequestProgressCallback progress_cb, void *progress_ctx, char *errmsg)
3349 {
3350  YRETCODE res;
3351  YIOHDL_internal *internalio;
3352 #ifdef DEBUG_YAPI_REQ
3353  int req_count = YREQ_LOG_START("SyncStartEx", device, request, requestsize);
3354  u64 start_tm = yapiGetTickCount();
3355 #endif
3356 
3357 
3358  if (!yContext)
3359  return YERR(YAPI_NOT_INITIALIZED);
3360 
3361 
3362  *reply = NULL;
3363  internalio = yMalloc(sizeof(YIOHDL_internal));
3364  memset((u8 *)iohdl, 0, YIOHDL_SIZE);
3365  if (YISERR(res = yapiRequestOpen(internalio, tcpchan, device, request, requestsize, NULL, NULL, progress_cb, progress_ctx, errmsg))) {
3366  yFree(internalio);
3367  } else {
3368 
3369  if (internalio->type == YIO_USB) {
3370  res = yapiRequestWaitEndUSB(internalio, reply, replysize, errmsg);
3371  } else if (internalio->type == YIO_TCP) {
3372  res = yapiRequestWaitEndHTTP(internalio, reply, replysize, errmsg);
3373  } else if (internalio->type == YIO_WS) {
3374  res = yapiRequestWaitEndWS(internalio, reply, replysize, errmsg);
3375  } else {
3376  yFree(internalio);
3377  return YERR(YAPI_INVALID_ARGUMENT);
3378  }
3379 
3381  *iohdl = internalio;
3382  internalio->next = yContext->yiohdl_first;
3383  yContext->yiohdl_first = internalio;
3385  }
3386 #ifdef DEBUG_YAPI_REQ
3387  if (res < 0) {
3388  YREQ_LOG_APPEND_ERR(req_count, "SyncStartEx", errmsg, res, start_tm);
3389  } else {
3390  YREQ_LOG_APPEND(req_count, "SyncStartEx", *reply, *replysize, start_tm);
3391  }
3392 #endif
3393 
3394  return res;
3395 }
3396 
3397 
3399 {
3400  YIOHDL_internal *r, *p, *arg = *iohdl;
3401  if(!yContext)
3402  return YERR(YAPI_NOT_INITIALIZED);
3403 
3404  if(iohdl == NULL)
3405  return YERR(YAPI_INVALID_ARGUMENT);
3406 
3407 
3409  r = yContext->yiohdl_first;
3410  p = NULL;
3411  while(r && r != arg) {
3412  p = r;
3413  r = r->next;
3414  }
3415  if (r ==NULL || r != arg) {
3417  return YERR(YAPI_INVALID_ARGUMENT);
3418  }
3419  if (p == NULL) {
3420  yContext->yiohdl_first = r->next;
3421  } else {
3422  p->next = r->next;
3423  }
3425 
3426 
3427 
3428 
3429  if(arg->type == YIO_USB) {
3430  yUsbClose(arg, errmsg);
3431  } else if(arg->type == YIO_TCP) {
3432  RequestSt *tcpreq = yContext->tcpreq[arg->tcpreqidx];
3433  yReqClose(tcpreq);
3434  } else {
3435  yReqClose(arg->ws);
3436  yReqFree(arg->ws);
3437  }
3438  yFree(arg);
3439  memset((u8 *)iohdl, 0, YIOHDL_SIZE);
3440  return YAPI_SUCCESS;
3441 }
3442 
3443 
3444 
3445 
3446 static void asyncDrop(void *context, const u8 *result, u32 resultlen, int retcode, const char *errmsg)
3447 {
3448 #ifdef DEBUG_YAPI_REQ
3449  int req_count = (int)(((u8*)context) - ((u8*)NULL));
3450  YREQ_LOG_APPEND(req_count, "ASync", result, resultlen, 0);
3451 #endif
3452 }
3453 
3454 
3455 static YRETCODE yapiHTTPRequestAsyncEx_internal(int tcpchan, const char *device, const char *request, int len, yapiRequestAsyncCallback callback, void *context, char *errmsg)
3456 {
3457  YIOHDL_internal iohdl;
3458  YRETCODE res;
3459  int retryCount = 1;
3460 #ifdef DEBUG_YAPI_REQ
3461  int yreq_count = YREQ_LOG_START("ASync", device, request, len);
3462 #endif
3463 
3464  if(!yContext)
3465  return YERR(YAPI_NOT_INITIALIZED);
3466 
3467  do {
3468  if (callback == NULL) {
3469  callback = asyncDrop;
3470 #ifdef DEBUG_YAPI_REQ
3471  context = ((u8*)NULL) + yreq_count;
3472 #endif
3473  }
3474  res = yapiRequestOpen(&iohdl, tcpchan, device, request, len, callback, context, NULL,NULL,errmsg);
3475  if(YISERR(res)) {
3476  if (res == YAPI_UNAUTHORIZED) {
3477  return res;
3478  }
3479 
3480  if (retryCount){
3481  char suberr[YOCTO_ERRMSG_LEN];
3482  dbglog("ASync request for %s failed. Retrying after yapiUpdateDeviceList\n",device);
3483  if(YISERR(yapiUpdateDeviceList_internal(1, suberr))){
3484  dbglog("yapiUpdateDeviceList failled too with %s\n",errmsg);
3485  return res;
3486  }
3487  }
3488  }
3489  } while (res !=YAPI_SUCCESS && retryCount--);
3490 
3491  return res;
3492 }
3493 
3494 
3495 
3496 static int yapiHTTPRequest_internal(const char *device, const char *request, char* buffer, int buffsize, int *fullsize, char *errmsg)
3497 {
3498  YIOHDL iohdl;
3499  char *reply=NULL;
3500  int replysize=0;
3501 
3502  if(!buffer || buffsize < 4){
3503  return YERR(YAPI_INVALID_ARGUMENT);
3504  }
3505  YPROPERR(yapiHTTPRequestSyncStartEx_internal(&iohdl, 0, device, request, YSTRLEN(request), &reply, &replysize, NULL, NULL, errmsg));
3506 
3507  if (fullsize)
3508  *fullsize = replysize;
3509 
3510  if(replysize > buffsize-1) {
3511  replysize = buffsize-1;
3512  }
3513  memcpy(buffer, reply, replysize);
3514  buffer[replysize] = 0;
3515  YPROPERR(yapiHTTPRequestSyncDone_internal(&iohdl, errmsg));
3516  return replysize;
3517 }
3518 
3520 {
3521  char errmsg[YOCTO_ERRMSG_LEN];
3522  if (!yContext) {
3523  yapiInitAPI_internal(0, errmsg);
3524  }
3525  if (yContext) {
3526  yContext->hubDiscoveryCallback = hubDiscoveryCallback;
3527  }
3528 }
3529 
3531 {
3532  if(!yContext)
3533  return YERR(YAPI_NOT_INITIALIZED);
3534  // ensure SSDP thread is started
3536  // triger SSDP discovery
3537  return (YRETCODE) ySSDPDiscover(&yContext->SSDP,errmsg);
3538 }
3539 
3540 // used only by VirtualHub
3541 YRETCODE yapiGetBootloadersDevs(char *serials,unsigned int maxNbSerial, unsigned int *totalBootladers, char *errmsg)
3542 {
3543  int nbifaces=0;
3544  yInterfaceSt *iface;
3545  yInterfaceSt *runifaces=NULL;
3546  int i;
3547  u32 totalBoot,copyedBoot;
3548  char *s=serials;
3549  YRETCODE res;
3550 
3551  if(!yContext)
3552  return YERR(YAPI_NOT_INITIALIZED);
3553 
3554  if((yContext->detecttype & Y_DETECT_USB) ==0) {
3555  return YERRMSG(YAPI_INVALID_ARGUMENT,"You must init the yAPI with Y_DETECT_USB flag");
3556  }
3557 
3558  if (YISERR(res = (YRETCODE) yyyUSBGetInterfaces(&runifaces,&nbifaces,errmsg))){
3559  return res;
3560  }
3561 
3562  totalBoot=copyedBoot=0;
3563 
3564  for(i=0, iface=runifaces ; i < nbifaces ; i++, iface++){
3565  if(iface->deviceid != YOCTO_DEVID_BOOTLOADER)
3566  continue;
3567  if(serials && copyedBoot < maxNbSerial){
3568  YSTRCPY(s,YOCTO_SERIAL_LEN*2,iface->serial);
3569  s+=YOCTO_SERIAL_LEN;
3570  copyedBoot++;
3571  }
3572  totalBoot++;
3573  }
3574  // free all tmp ifaces
3575  if(runifaces){
3576  yFree(runifaces);
3577  }
3578  if(totalBootladers)
3579  *totalBootladers=totalBoot;
3580 
3581  return (YRETCODE) copyedBoot;
3582 
3583 }
3584 
3585 //used by API
3586 static YRETCODE yapiGetBootloaders_internal(char *buffer, int buffersize, int *fullsize, char *errmsg)
3587 {
3588  int i;
3589  char *p = buffer;
3590  YRETCODE res;
3591  int size, total, len;
3592 
3593  if(!yContext)
3594  return YERR(YAPI_NOT_INITIALIZED);
3595 
3596  if(buffer==NULL || buffersize<1)
3597  return YERR(YAPI_INVALID_ARGUMENT);
3598 
3599  buffersize--;// reserve space for \0
3600 
3601  size = total = 0;
3602 
3603  if (yContext->detecttype & Y_DETECT_USB) {
3604  int nbifaces = 0;
3605  yInterfaceSt *iface;
3606  yInterfaceSt *runifaces = NULL;
3607 
3608  if (YISERR(res = (YRETCODE)yyyUSBGetInterfaces(&runifaces, &nbifaces, errmsg))){
3609  return res;
3610  }
3611 
3612  for (i = 0, iface = runifaces; i < nbifaces; i++, iface++){
3613  if (iface->deviceid != YOCTO_DEVID_BOOTLOADER)
3614  continue;
3615 
3616  if (buffer && size < buffersize && buffer != p) {
3617  *p++ = ',';
3618  size++;
3619  }
3620 
3621  len = YSTRLEN(iface->serial);
3622  total += len;
3623  if (buffer && size + len < buffersize){
3624  YSTRCPY(p, buffersize - size, iface->serial);
3625  p += len;
3626  size += len;
3627  }
3628  }
3629  // free all tmp ifaces
3630  if (runifaces){
3631  yFree(runifaces);
3632  }
3633 
3634  }
3635 
3636 
3637  for (i = 0; i < NBMAX_NET_HUB; i++){
3638  if (yContext->nethub[i]){
3639  char bootloaders[4 * YOCTO_SERIAL_LEN];
3640  char hubserial[YOCTO_SERIAL_LEN];
3641  int res, j;
3642  char *serial;
3644  res = yNetHubGetBootloaders(hubserial, bootloaders, errmsg);
3645  if (YISERR(res)) {
3646  return res;
3647  }
3648  for (j = 0, serial = bootloaders; j < res; j++, serial += YOCTO_SERIAL_LEN){
3649  if (buffer && size < buffersize && buffer != p) {
3650  *p++ = ',';
3651  size++;
3652  }
3653 
3654  len = YSTRLEN(serial);
3655  total += len;
3656  if (buffer && size + len < buffersize){
3657  YSTRCPY(p, buffersize - size, serial);
3658  p += len;
3659  size += len;
3660  }
3661  }
3662  }
3663  }
3664 
3665  //ensure buffer is null terminated;
3666  *p = 0;
3667  if(fullsize)
3668  *fullsize = total;
3669 
3670  return (YRETCODE) size;
3671 
3672 }
3673 
3674 #ifndef YAPI_IN_YDEVICE
3675 
3676 static int yapiGetSubdevices_internal(const char *serial, char *buffer, int buffersize, int *fullsize, char *errmsg)
3677 {
3678  int i;
3679  char *p = buffer;
3680  int size, total;
3681 
3682  if(!yContext)
3683  return YERR(YAPI_NOT_INITIALIZED);
3684 
3685  if(buffer==NULL || buffersize<1)
3686  return YERR(YAPI_INVALID_ARGUMENT);
3687 
3688  buffersize--;// reserve space for \0
3689  size = total = 0;
3690  for (i = 0; i < NBMAX_NET_HUB; i++) {
3691  char hubserial[YOCTO_SERIAL_LEN];
3692 
3693  if (yContext->nethub[i] == NULL)
3694  continue;
3695 
3697  if (YSTRCMP(serial, hubserial) == 0) {
3698  yStrRef knownDevices[128];
3699  int j, nbKnownDevices;
3700  nbKnownDevices = wpGetAllDevUsingHubUrl(yContext->nethub[i]->url, knownDevices, 128);
3701  total = nbKnownDevices * YOCTO_SERIAL_LEN + nbKnownDevices;
3702  if (buffersize > total) {
3703  int isfirst = 1;
3704  for (j = 0; j < nbKnownDevices; j++) {
3705  if (knownDevices[j] == yContext->nethub[i]->serial)
3706  continue;
3707  if (!isfirst)
3708  *p++ = ',';
3709  yHashGetStr(knownDevices[j], p, YOCTO_SERIAL_LEN);
3710  p += YSTRLEN(p);
3711  isfirst = 0;
3712  }
3713  }
3714  break;
3715  }
3716  }
3717 
3718  //ensure buffer is null terminated;
3719  size = (int) (p - buffer);
3720  *p++ = 0;
3721  if (fullsize)
3722  *fullsize = total;
3723 
3724  return size;
3725 
3726 }
3727 
3728 
3729 static const char* yapiJsonValueParseArray(yJsonStateMachine *j, const char *path, int *result, char *errmsg);
3730 
3731 
3733 {
3734 #ifdef DEBUG_JSON_PARSE
3735  dbglog("skip %s(%d):%s\n", yJsonStateStr[j->st], j->st, j->token);
3736 #endif
3737  yJsonParse(j);
3738  do {
3739 #ifdef DEBUG_JSON_PARSE
3740  dbglog("... %s(%d):%s\n", yJsonStateStr[j->st], j->st, j->token);
3741 #endif
3742  yJsonSkip(j, 1);
3743  } while (yJsonParse(j) == YJSON_PARSE_AVAIL && j->st != YJSON_PARSE_STRUCT);
3744 }
3745 
3746 
3748 {
3749 #ifdef DEBUG_JSON_PARSE
3750  dbglog("skip %s(%d):%s\n", yJsonStateStr[j->st], j->st, j->token);
3751 #endif
3752  yJsonParse(j);
3753  do {
3754 #ifdef DEBUG_JSON_PARSE
3755  dbglog("... %s(%d):%s\n", yJsonStateStr[j->st], j->st, j->token);
3756 #endif
3757  yJsonSkip(j, 1);
3758  } while (yJsonParse(j) == YJSON_PARSE_AVAIL && j->st != YJSON_PARSE_ARRAY);
3759 }
3760 
3761 
3762 static const char* yapiJsonValueParseStruct(yJsonStateMachine *j, const char *path, int *result, char *errmsg)
3763 {
3764 
3765  int len = 0;
3766  const char *p = path;
3767 
3768  while (*p && *p != '|'){
3769  p++;
3770  len++;
3771  }
3772 
3773  while (yJsonParse(j) == YJSON_PARSE_AVAIL) {
3774  if (j->st == YJSON_PARSE_MEMBNAME) {
3775  if (YSTRNCMP(path, j->token, len) == 0){
3776  if (*p) {
3777 #ifdef DEBUG_JSON_PARSE
3778  dbglog("recurse %s %s(%d):%s\n", j->token, yJsonStateStr[j->st], j->st, j->token);
3779 #endif
3780  yJsonParse(j);
3781  if (j->st == YJSON_PARSE_STRUCT) {
3782  return yapiJsonValueParseStruct(j, ++p, result, errmsg);
3783  } else if (j->st == YJSON_PARSE_ARRAY) {
3784  return yapiJsonValueParseArray(j, ++p, result, errmsg);
3785  } else{
3786  *result = YERRMSG(YAPI_INVALID_ARGUMENT, "Invalid JSON struct");
3787  return "";
3788  }
3789  } else{
3790  const char *start_of_json;
3791 #ifdef DEBUG_JSON_PARSE
3792  dbglog("found %s %s(%d):%s\n", j->token, yJsonStateStr[j->st], j->st, j->token);
3793 #endif
3794  yJsonParse(j);
3795  start_of_json = j->state_start;
3796  switch (j->st){
3797  case YJSON_PARSE_STRING:
3798  while (j->next == YJSON_PARSE_STRINGCONT) {
3799  yJsonParse(j);
3800  }
3801  case YJSON_PARSE_NUM:
3802  *result = (u32)(j->state_end - start_of_json);
3803  return start_of_json;
3804  case YJSON_PARSE_STRUCT:
3805  skipJsonStruct(j);
3806  *result = (u32)(j->state_end - start_of_json);
3807  return start_of_json;
3808  case YJSON_PARSE_ARRAY:
3809  skipJsonArray(j);
3810  *result = (u32)(j->state_end - start_of_json);
3811  return start_of_json;
3812  default:
3813  *result = YERRMSG(YAPI_INVALID_ARGUMENT, "Only String and numerical target are supported");
3814  return "";
3815  }
3816  }
3817  } else {
3818 #ifdef DEBUG_JSON_PARSE
3819  dbglog("skip %s %s(%d):%s\n", j->token, yJsonStateStr[j->st], j->st, j->token);
3820 #endif
3821  yJsonSkip(j, 1);
3822  }
3823  }
3824 #ifdef DEBUG_JSON_PARSE
3825  else{
3826  dbglog("%s(%d):%s\n", yJsonStateStr[j->st], j->st, j->token);
3827  }
3828 #endif
3829  }
3830  *result = YERRMSG(YAPI_INVALID_ARGUMENT, "Path not found");
3831  return "";
3832 }
3833 
3834 
3835 static const char* yapiJsonValueParseArray(yJsonStateMachine *j, const char *path, int *result, char *errmsg)
3836 {
3837 
3838  int len = 0;
3839  const char *p = path;
3840  char buffer[16];
3841  int index, count = 0;
3842  yJsonState array_type;
3843 
3844  while (*p && *p != '|'){
3845  p++;
3846  len++;
3847  }
3848  YASSERT(len < 16);
3849  memcpy(buffer, path, len);
3850  buffer[len] = 0;
3851  index = atoi(buffer);
3852 
3853  if (yJsonParse(j) != YJSON_PARSE_AVAIL) {
3854  *result = YERRMSG(YAPI_INVALID_ARGUMENT, "Invalid JSON array");
3855  return "";
3856  }
3857 
3858  array_type = j->st;
3859  if (j->st != YJSON_PARSE_STRUCT) {
3860 #ifdef DEBUG_JSON_PARSE
3861  dbglog("debug %s %s(%d):%s\n", j->token, yJsonStateStr[j->st], j->st, j->token);
3862 #endif
3863  *result = YERRMSG(YAPI_NOT_SUPPORTED, "Unsupported JSON array");
3864  return "";
3865  }
3866  do {
3867  if (index == count) {
3868  return yapiJsonValueParseStruct(j, ++p, result, errmsg);
3869  } else {
3870 #ifdef DEBUG_JSON_PARSE
3871  dbglog("skip %s(%d):%s\n", yJsonStateStr[j->st], j->st, j->token);
3872 #endif
3873  yJsonParse(j);
3874  do {
3875 #ifdef DEBUG_JSON_PARSE
3876  dbglog("... %s(%d):%s\n", yJsonStateStr[j->st], j->st, j->token);
3877 #endif
3878  yJsonSkip(j, 1);
3879  } while (yJsonParse(j) == YJSON_PARSE_AVAIL && j->st != array_type);
3880  }
3881  count++;
3882  } while (yJsonParse(j) == YJSON_PARSE_AVAIL);
3883 
3884  *result = YERRMSG(YAPI_INVALID_ARGUMENT, "Path not found");
3885  return "";
3886 }
3887 
3888 
3889 static int yapiJsonDecodeString_internal(const char *json_string, char *output)
3890 {
3892  char *p = output;
3893  int maxsize = YSTRLEN(json_string);
3894 
3895  j.src = json_string;
3896  j.end = j.src + maxsize;
3897  j.st = YJSON_START;
3898  yJsonParse(&j);
3899  do {
3900  int len = YSTRLEN(j.token);
3901  yMemcpy(p, j.token, len);
3902  p += len;
3903  } while (j.next == YJSON_PARSE_STRINGCONT && yJsonParse(&j) == YJSON_PARSE_AVAIL);
3904  *p = 0;
3905 
3906  return (u32)(p - output);
3907 }
3908 
3909 
3910 
3911 
3912 int yapiJsonGetPath_internal(const char *path, const char *json_data, int json_size, int withHTTPheader, const char **output, char *errmsg)
3913 {
3915  int result;
3916 
3917  j.src = json_data;
3918  j.end = j.src + json_size;
3919  if (withHTTPheader) {
3920  j.st = YJSON_HTTP_START;
3921  if (yJsonParse(&j) != YJSON_PARSE_AVAIL || j.st != YJSON_HTTP_READ_CODE) {
3922  return YERRMSG(YAPI_IO_ERROR, "Failed to parse HTTP header");
3923  }
3924  if (YSTRCMP(j.token, "200")) {
3925  return YERRMSG(YAPI_IO_ERROR, "Unexpected HTTP return code");
3926  }
3927  if (yJsonParse(&j) != YJSON_PARSE_AVAIL || j.st != YJSON_HTTP_READ_MSG) {
3928  return YERRMSG(YAPI_IO_ERROR, "Unexpected JSON reply format");
3929  }
3930  }else {
3931  j.st = YJSON_START;
3932  }
3933  if (yJsonParse(&j) != YJSON_PARSE_AVAIL || j.st != YJSON_PARSE_STRUCT) {
3934  *output = "";
3935  return YERRMSG(YAPI_INVALID_ARGUMENT, "Not a JSON struct");
3936  }
3937 
3938  *output = yapiJsonValueParseStruct(&j, path, &result, errmsg);
3939  return result;
3940 }
3941 
3942 
3943 typedef struct _fullAttrInfo {
3944  char func[32];
3945  char attr[32];
3946  char value[256];
3947 } fullAttrInfo;
3948 
3949 
3950 
3951 static fullAttrInfo* parseSettings(const char *settings, int *count)
3952 {
3954  int nbAttr=0,allocAttr=0;
3955  fullAttrInfo *attrBuff=NULL;
3956  char func[32];
3957  char attr[32];
3958 
3959  // Parse HTTP header
3960  j.src = settings;
3961  j.end = j.src + YSTRLEN(settings);
3962  j.st = YJSON_START;
3963  if(yJsonParse(&j) != YJSON_PARSE_AVAIL || j.st != YJSON_PARSE_STRUCT) {
3964  nbAttr = -1;
3965  goto exit;
3966  }
3967  while (yJsonParse(&j) == YJSON_PARSE_AVAIL && j.st == YJSON_PARSE_MEMBNAME) {
3968  YSTRCPY(func,32,j.token);
3969  if (YSTRCMP(j.token, "services") == 0){
3970  yJsonSkip(&j, 1);
3971  } else{
3972  if (yJsonParse(&j) != YJSON_PARSE_AVAIL || j.st != YJSON_PARSE_STRUCT) {
3973  nbAttr = -1;
3974  goto exit;
3975  }
3976  while (yJsonParse(&j) == YJSON_PARSE_AVAIL && j.st == YJSON_PARSE_MEMBNAME) {
3977  YSTRCPY(attr, 32, j.token);
3978  if (yJsonParse(&j) != YJSON_PARSE_AVAIL) {
3979  nbAttr = -1;
3980  goto exit;
3981  }
3982 
3983  if (j.st != YJSON_PARSE_STRUCT) {
3984  if (nbAttr == allocAttr) {
3985  //grow the buffer
3986  fullAttrInfo *tmp = attrBuff;
3987  if (allocAttr){
3988  allocAttr *= 2;
3989  } else {
3990  allocAttr = 64;
3991  }
3992  attrBuff = yMalloc(allocAttr * sizeof(fullAttrInfo));
3993  if (tmp) {
3994  memcpy(attrBuff, tmp, nbAttr * sizeof(fullAttrInfo));
3995  yFree(tmp);
3996  }
3997  }
3998  YSTRCPY(attrBuff[nbAttr].func, 32, func);
3999  YSTRCPY(attrBuff[nbAttr].attr, 32, attr);
4000  YSPRINTF(attrBuff[nbAttr].value, 256, "%s", j.token);
4001  while (j.next == YJSON_PARSE_STRINGCONT && yJsonParse(&j) == YJSON_PARSE_AVAIL) {
4002  YSTRCAT(attrBuff[nbAttr].value, 256, j.token);
4003  }
4004  nbAttr++;
4005  } else {
4006  do {
4007  yJsonParse(&j);
4008  } while (j.st != YJSON_PARSE_STRUCT);
4009  }
4010  }
4011  if (j.st != YJSON_PARSE_STRUCT){
4012  nbAttr = -1;
4013  goto exit;
4014  }
4015  }
4016  }
4017  if(j.st != YJSON_PARSE_STRUCT) {
4018  nbAttr = -1;
4019  goto exit;
4020  }
4021 exit:
4022  *count = nbAttr;
4023  if (nbAttr < 0 && attrBuff) {
4024  yFree(attrBuff);
4025  attrBuff = NULL;
4026  }
4027  return attrBuff;
4028 }
4029 
4030 
4031 
4032 static YRETCODE yapiGetAllJsonKeys_internal(const char *json_buffer, char *buffer, int buffersize, int *fullsize, char *errmsg)
4033 {
4034  fullAttrInfo *attrs;
4035  int attrs_count;
4036  int j, totalsize=0;
4037  int len;
4038  const char *sep = "";
4039 
4040  attrs = parseSettings(json_buffer, &attrs_count);
4041  if (!attrs) {
4042  return YERR(YAPI_IO_ERROR);
4043  }
4044 
4045  if (buffersize < 16) {
4046  return YERRMSG(YAPI_INVALID_ARGUMENT, "buffer too small");;
4047  }
4048 
4049  buffer[0] = '[';
4050  totalsize++;
4051 
4052  for (j = 0; j < attrs_count; j++) {
4053  char tmpbuf[1024];
4054  char *p, *d;
4055  len = YSPRINTF(tmpbuf, 1024, "%s\"%s/%s=", sep, attrs[j].func, attrs[j].attr);
4056  if (len < 0) {
4057  yFree(attrs);
4058  return YERR(YAPI_IO_ERROR);
4059  }
4060  p = attrs[j].value;
4061  d = tmpbuf + len;
4062  while (*p && len < 1020) {
4063  if (*p == '"' || *p == '\\') {
4064  *d++ = '\\';
4065  len++;
4066  }
4067  *d++ = *p++;
4068  len++;
4069 
4070  }
4071  *d = 0;
4072  YSTRCAT(d, 1024-len, "\"");
4073  len ++;
4074  YASSERT(len == YSTRLEN(tmpbuf));
4075  sep = ",";
4076  if (buffersize > totalsize+len) {
4077  memcpy(buffer + totalsize, tmpbuf, len);
4078  }
4079  totalsize += len;
4080  }
4081 
4082  if (buffersize > totalsize ) {
4083  buffer[totalsize] = ']';
4084  }
4085  totalsize++;
4086  *fullsize = totalsize;
4087  yFree(attrs);
4088  return YAPI_SUCCESS;
4089 }
4090 
4091 #endif
4092 
4094 {
4095  if(!yContext)
4096  return;
4097 
4099  yContext->rawNotificationCb = callback;
4101 }
4102 
4104 {
4105  if(!yContext)
4106  return;
4107 
4109  yContext->rawReportCb = callback;
4111 }
4112 
4114 {
4115  if(!yContext)
4116  return;
4117 
4119  yContext->rawReportV2Cb = callback;
4121 }
4122 
4123 
4124 //#define YDLL_TRACE_FILE "dll_trace.txt"
4125 
4126 #ifdef YDLL_TRACE_FILE
4127 
4128 typedef enum
4129 {
4130  trcInitAPI = 0,
4131  trcFreeAPI,
4132  trcRegisterLogFunction,
4133  trcRegisterDeviceLogCallback,
4134  trcStartStopDeviceLogCallback,
4135  trcRegisterDeviceArrivalCallback,
4136  trcRegisterDeviceRemovalCallback,
4137  trcRegisterDeviceChangeCallback,
4138  trcRegisterFunctionUpdateCallback,
4139  trcRegisterTimedReportCallback,
4140  trcLockFunctionCallBack,
4141  trcUnlockFunctionCallBack,
4142  trcLockDeviceCallBack,
4143  trcUnlockDeviceCallBack,
4144  trcTestHub,
4145  trcRegisterHub,
4146  trcPreregisterHub,
4147  trcUnregisterHub,
4148  trcUpdateDeviceList,
4149  trcHandleEvents,
4150  trcSleep,
4151  trcCheckLogicalName,
4152  trcGetAPIVersion,
4153  trcSetTraceFile,
4154  trcGetDevice,
4155  trcGetAllDevices,
4156  trcGetDeviceInfo,
4157  trcGetDevicePath,
4158  trcGetDevicePathEx,
4159  trcGetFunction,
4160  trcGetFunctionsByClass,
4161  trcGetFunctionsByDevice,
4162  trcGetFunctionInfo,
4163  trcGetFunctionInfoEx,
4164  trcHTTPRequestSyncStartEx,
4165  trcHTTPRequestSyncStart,
4166  trcHTTPRequestSyncStartOutOfBand,
4167  trcHTTPRequestSyncDone,
4168  trcHTTPRequestAsyncEx,
4169  trcHTTPRequestAsync,
4170  trcHTTPRequestAsyncOutOfBand,
4171  trcHTTPRequest,
4172  trcRegisterHubDiscoveryCallback,
4173  trcTriggerHubDiscovery,
4174  trcGetBootloaders,
4175  trcJsonDecodeString,
4176  trcJsonGetPath,
4177  trcGetAllJsonKeys,
4178  trcCheckFirmware,
4179  trcUpdateFirmware,
4180  trcUpdateFirmwareEx,
4181  trcGetSubdevices,
4182  trcGetMem,
4183  trcFreeMem,
4184  trcGetSubDevcies
4185 } TRC_FUN;
4186 
4187 static const char * trc_funname[] =
4188 {
4189  "initApi",
4190  "freeApi",
4191  "RegLog",
4192  "RegDeviceLog",
4193  "StartStopDevLog",
4194  "RegDeviceArrival",
4195  "RegDeviceRemoval",
4196  "RegDeviceChange",
4197  "RegUpdateCallback",
4198  "RegTimedCallback",
4199  "LockFunCback",
4200  "UnLockFunCback",
4201  "LockDeviceCback",
4202  "UnLockDeviceCback",
4203  "TestHub",
4204  "RegHub",
4205  "PreRegHub",
4206  "UnRegHub",
4207  "UpDL",
4208  "HE",
4209  "Sl",
4210  "CheckLName",
4211  "GetAPIVersion",
4212  "SetTrcFile",
4213  "GDev",
4214  "GAllDev",
4215  "GDevInfo",
4216  "GDevPath",
4217  "GDevPathEx",
4218  "GFun",
4219  "GFunByClass",
4220  "GFunByDev",
4221  "GFunInfo",
4222  "GFunInfoEx",
4223  "ReqSyncStartEx",
4224  "ReqSyncStart",
4225  "ReqSyncStartOB",
4226  "ReqSyncDone",
4227  "ReqAsyncEx",
4228  "ReqAsync",
4229  "ReqAsyncOB",
4230  "Req",
4231  "RegHubDiscovery",
4232  "THubDiscov",
4233  "GBoot",
4234  "JsonDecStr",
4235  "JsonGetPath",
4236  "GAllJsonK",
4237  "CkFw",
4238  "UpFw",
4239  "UpFwEx",
4240  "GetSubdev",
4241  "getmem",
4242  "freemem",
4243  "getsubdev"
4244 };
4245 
4246 static const char *dlltracefile = YDLL_TRACE_FILE;
4247 
4248 static void write_line(const char *ptr, int len)
4249 {
4250  FILE *f;
4251  if (YFOPEN(&f,dlltracefile,"a+") != 0) {
4252  return;
4253  }
4254  fwrite(ptr,1,len,f);
4255  fclose(f);
4256 
4257 }
4258 
4259 static u64 trc_basetime = 0;
4260 
4261 static void trace_dll(u64 t, char prefix, TRC_FUN trcfun, const char *action)
4262 {
4263  char buffer[512];
4264  if (trc_basetime == 0) {
4265  trc_basetime = t;
4266  }
4267  int len = YSPRINTF(buffer, 512, "%"FMTu64"%c%s%s\n", (t-trc_basetime), prefix, trc_funname[trcfun], action);
4268  write_line(buffer, len);
4269 }
4270 
4271 #define YDLL_CALL_ENTER(funname) TRC_FUN trcfun = funname;\
4272  u64 dll_start, dll_stop;\
4273  char dbg_msg[128];\
4274  dll_start = yapiGetTickCount();\
4275  trace_dll(dll_start, '>' ,trcfun, "");
4276 
4277 #define YDLL_CALL_LEAVEVOID() dll_stop = yapiGetTickCount();\
4278  YSPRINTF(dbg_msg, 128, ":%"FMTs64, (dll_stop - dll_start)); \
4279  trace_dll(dll_start, '<' ,trcfun, dbg_msg);
4280 
4281 #define YDLL_CALL_LEAVE(value) dll_stop = yapiGetTickCount();\
4282  YSPRINTF(dbg_msg, 128, ":%d=%"FMTx64, (dll_stop - dll_start), (int)(value), (u64)(value)); \
4283  trace_dll(dll_start, '<' ,trcfun, dbg_msg);
4284 #define YDLL_CALL_LEAVEPTR(value) dll_stop = yapiGetTickCount();\
4285  YSPRINTF(dbg_msg, 128, ":%p", (dll_stop - dll_start), (value)); \
4286  trace_dll(dll_start, '<' ,trcfun, dbg_msg);
4287 #else
4288 #define YDLL_CALL_ENTER(funname)
4289 #define YDLL_CALL_LEAVEVOID()
4290 #define YDLL_CALL_LEAVE(value)
4291 #define YDLL_CALL_LEAVEPTR(value)
4292 #endif
4293 
4294 
4295 YRETCODE YAPI_FUNCTION_EXPORT yapiInitAPI(int detect_type, char *errmsg)
4296 {
4297  YRETCODE res;
4298  YDLL_CALL_ENTER(trcInitAPI);
4299  res = yapiInitAPI_internal(detect_type, errmsg);
4300  YDLL_CALL_LEAVE(res);
4301  return res;
4302 }
4303 
4305 {
4306  YDLL_CALL_ENTER(trcFreeAPI);
4309 }
4310 
4312 {
4313  YDLL_CALL_ENTER(trcRegisterLogFunction);
4316 }
4317 
4319 {
4320  YDLL_CALL_ENTER(trcRegisterDeviceLogCallback);
4323 }
4324 
4325 void YAPI_FUNCTION_EXPORT yapiStartStopDeviceLogCallback(const char *serial, int start)
4326 {
4327  YDLL_CALL_ENTER(trcStartStopDeviceLogCallback);
4330 }
4331 
4333 {
4334  YDLL_CALL_ENTER(trcRegisterDeviceArrivalCallback);
4337 }
4338 
4340 {
4341  YDLL_CALL_ENTER(trcRegisterDeviceRemovalCallback);
4344 }
4345 
4347 {
4348  YDLL_CALL_ENTER(trcRegisterDeviceChangeCallback);
4351 }
4352 
4354 {
4355  YDLL_CALL_ENTER(trcRegisterFunctionUpdateCallback);
4358 }
4359 
4361 {
4362  YDLL_CALL_ENTER(trcRegisterTimedReportCallback);
4363  yapiRegisterTimedReportCallback_internal(timedReportCallback);
4365 }
4366 
4368 {
4369  YRETCODE res;
4370  YDLL_CALL_ENTER(trcLockFunctionCallBack);
4371  res = yapiLockFunctionCallBack_internal(errmsg);
4372  YDLL_CALL_LEAVE(res);
4373  return res;
4374 }
4375 
4377 {
4378  YRETCODE res;
4379  YDLL_CALL_ENTER(trcUnlockFunctionCallBack);
4381  YDLL_CALL_LEAVE(res);
4382  return res;
4383 }
4384 
4386 {
4387  YRETCODE res;
4388  YDLL_CALL_ENTER(trcLockDeviceCallBack);
4389  res = yapiLockDeviceCallBack_internal(errmsg);
4390  YDLL_CALL_LEAVE(res);
4391  return res;
4392 }
4393 
4395 {
4396  YRETCODE res;
4397  YDLL_CALL_ENTER(trcUnlockDeviceCallBack);
4398  res = yapiUnlockDeviceCallBack_internal(errmsg);
4399  YDLL_CALL_LEAVE(res);
4400  return res;
4401 }
4402 
4403 YRETCODE YAPI_FUNCTION_EXPORT yapiTestHub(const char *url, int mstimeout, char *errmsg)
4404 {
4405  YRETCODE res;
4406  YDLL_CALL_ENTER(trcTestHub);
4407  res = yapiTestHub_internal(url, mstimeout, errmsg);
4408  YDLL_CALL_LEAVE(res);
4409  return res;
4410 }
4411 
4412 YRETCODE YAPI_FUNCTION_EXPORT yapiRegisterHub(const char *url, char *errmsg)
4413 {
4414  YRETCODE res;
4415  YDLL_CALL_ENTER(trcRegisterHub);
4416  res = yapiRegisterHub_internal(url, errmsg);
4417  YDLL_CALL_LEAVE(res);
4418  return res;
4419 }
4420 
4421 YRETCODE YAPI_FUNCTION_EXPORT yapiPreregisterHub(const char *url, char *errmsg)
4422 {
4423  YRETCODE res;
4424  YDLL_CALL_ENTER(trcPreregisterHub);
4425  res = yapiPreregisterHub_internal(url, errmsg);
4426  YDLL_CALL_LEAVE(res);
4427  return res;
4428 }
4429 
4431 {
4432  YDLL_CALL_ENTER(trcUnregisterHub);
4435 }
4436 
4438 {
4439  YRETCODE res;
4440  YDLL_CALL_ENTER(trcUpdateDeviceList);
4441  res = yapiUpdateDeviceList_internal(forceupdate, errmsg);
4442  YDLL_CALL_LEAVE(res);
4443  return res;
4444 }
4445 
4447 {
4448  YRETCODE res;
4449  YDLL_CALL_ENTER(trcHandleEvents);
4450  res = yapiHandleEvents_internal(errmsg);
4451  YDLL_CALL_LEAVE(res);
4452  return res;
4453 }
4454 
4455 YRETCODE YAPI_FUNCTION_EXPORT yapiSleep(int ms_duration, char *errmsg)
4456 {
4457  YRETCODE res;
4458  YDLL_CALL_ENTER(trcSleep);
4459  res = yapiSleep_internal(ms_duration, errmsg);
4460  YDLL_CALL_LEAVE(res);
4461  return res;
4462 }
4463 
4465 {
4466  int res;
4467  YDLL_CALL_ENTER(trcCheckLogicalName);
4468  res = yapiCheckLogicalName_internal(name);
4469  YDLL_CALL_LEAVE(res);
4470  return res;
4471 }
4472 u16 YAPI_FUNCTION_EXPORT yapiGetAPIVersion(const char **version, const char **apidate)
4473 {
4474  u16 res;
4475  YDLL_CALL_ENTER(trcGetAPIVersion);
4476  res = yapiGetAPIVersion_internal(version, apidate);
4477  YDLL_CALL_LEAVE(res);
4478  return res;
4479 }
4480 
4482 {
4483  YDLL_CALL_ENTER(trcSetTraceFile);
4486 }
4487 
4488 YAPI_DEVICE YAPI_FUNCTION_EXPORT yapiGetDevice(const char *device_str, char *errmsg)
4489 {
4490  YAPI_DEVICE res;
4491  YDLL_CALL_ENTER(trcGetDevice);
4492  res = yapiGetDevice_internal(device_str, errmsg);
4493  YDLL_CALL_LEAVE(res);
4494  return res;
4495 }
4496 
4497 int YAPI_FUNCTION_EXPORT yapiGetAllDevices(YAPI_DEVICE *buffer, int maxsize, int *neededsize, char *errmsg)
4498 {
4499  int res;
4500  YDLL_CALL_ENTER(trcGetAllDevices);
4501  res = yapiGetAllDevices_internal(buffer, maxsize, neededsize, errmsg);
4502  YDLL_CALL_LEAVE(res);
4503  return res;
4504 }
4505 
4507 {
4508  YRETCODE res;
4509  YDLL_CALL_ENTER(trcGetDeviceInfo);
4510  res = yapiGetDeviceInfo_internal(devdesc, infos, errmsg);
4511  YDLL_CALL_LEAVE(res);
4512  return res;
4513 }
4514 
4515 YRETCODE YAPI_FUNCTION_EXPORT yapiGetDevicePath(YAPI_DEVICE devdesc, char *rootdevice, char *request, int requestsize, int *neededsize, char *errmsg)
4516 {
4517  YRETCODE res;
4518  YDLL_CALL_ENTER(trcGetDevicePath);
4519  res = yapiGetDevicePath_internal(devdesc, rootdevice, request, requestsize, neededsize, errmsg);
4520  YDLL_CALL_LEAVE(res);
4521  return res;
4522 }
4523 
4524 YRETCODE YAPI_FUNCTION_EXPORT yapiGetDevicePathEx(const char * serial, char *rootdevice, char *request, int requestsize, int *neededsize, char *errmsg)
4525 {
4526  YRETCODE res;
4527  YDLL_CALL_ENTER(trcGetDevicePathEx);
4528  res = yapiGetDevicePathEx_internal(serial, rootdevice, request, requestsize, neededsize, errmsg);
4529  YDLL_CALL_LEAVE(res);
4530  return res;
4531 }
4532 
4533 YAPI_FUNCTION YAPI_FUNCTION_EXPORT yapiGetFunction(const char *class_str, const char *function_str,char *errmsg)
4534 {
4535  YAPI_FUNCTION res;
4536  YDLL_CALL_ENTER(trcGetFunction);
4537  res = yapiGetFunction_internal(class_str, function_str, errmsg);
4538  YDLL_CALL_LEAVE(res);
4539  return res;
4540 }
4541 
4542 int YAPI_FUNCTION_EXPORT yapiGetFunctionsByClass(const char *class_str, YAPI_FUNCTION prevfundesc,
4543  YAPI_FUNCTION *buffer, int maxsize, int *neededsize, char *errmsg)
4544 {
4545  int res;
4546  YDLL_CALL_ENTER(trcGetFunctionsByClass);
4547  res = yapiGetFunctionsByClass_internal(class_str, prevfundesc, buffer, maxsize, neededsize, errmsg);
4548  YDLL_CALL_LEAVE(res);
4549  return res;
4550 }
4551 
4553  YAPI_FUNCTION *buffer, int maxsize, int *neededsize, char *errmsg)
4554 {
4555  int res;
4556  YDLL_CALL_ENTER(trcGetFunctionsByDevice);
4557  res = yapiGetFunctionsByDevice_internal(devdesc, prevfundesc, buffer, maxsize, neededsize, errmsg);
4558  YDLL_CALL_LEAVE(res);
4559  return res;
4560 }
4561 
4562 YRETCODE YAPI_FUNCTION_EXPORT yapiGetFunctionInfo(YAPI_FUNCTION fundesc, YAPI_DEVICE *devdesc, char *serial, char *funcId, char *funcName, char *funcVal, char *errmsg)
4563 {
4564  YRETCODE res;
4565  YDLL_CALL_ENTER(trcGetFunctionInfo);
4566  res = yapiGetFunctionInfoEx_internal(fundesc, devdesc, serial, funcId, NULL, funcName, funcVal, errmsg);
4567  YDLL_CALL_LEAVE(res);
4568  return res;
4569 }
4570 
4571 
4572 YRETCODE YAPI_FUNCTION_EXPORT yapiGetFunctionInfoEx(YAPI_FUNCTION fundesc, YAPI_DEVICE *devdesc, char *serial, char *funcId, char *baseType, char *funcName, char *funcVal, char *errmsg)
4573 {
4574  YRETCODE res;
4575  YDLL_CALL_ENTER(trcGetFunctionInfoEx);
4576  res = yapiGetFunctionInfoEx_internal(fundesc, devdesc, serial, funcId, baseType, funcName, funcVal, errmsg);
4577  YDLL_CALL_LEAVE(res);
4578  return res;
4579 }
4580 
4581 
4582 YRETCODE YAPI_FUNCTION_EXPORT yapiHTTPRequestSyncStartEx(YIOHDL *iohdl, const char *device, const char *request, int requestsize, char **reply, int *replysize, char *errmsg)
4583 {
4584  YRETCODE res;
4585  YDLL_CALL_ENTER(trcHTTPRequestSyncStartEx);
4586  res = yapiHTTPRequestSyncStartEx_internal(iohdl, 0, device, request, requestsize, reply, replysize, NULL, NULL, errmsg);
4587  YDLL_CALL_LEAVE(res);
4588  return res;
4589 }
4590 
4591 YRETCODE YAPI_FUNCTION_EXPORT yapiHTTPRequestSyncStart(YIOHDL *iohdl, const char *device, const char *request, char **reply, int *replysize, char *errmsg)
4592 {
4593  YRETCODE res;
4594  YDLL_CALL_ENTER(trcHTTPRequestSyncStart);
4595  res = yapiHTTPRequestSyncStartEx_internal(iohdl, 0, device, request, YSTRLEN(request), reply, replysize, NULL, NULL, errmsg);
4596  YDLL_CALL_LEAVE(res);
4597  return res;
4598 }
4599 
4600 
4601 YRETCODE YAPI_FUNCTION_EXPORT yapiHTTPRequestSyncStartOutOfBand(YIOHDL *iohdl, int channel, const char *device, const char *request, int requestsize, char **reply, int *replysize, yapiRequestProgressCallback progress_cb, void *progress_ctx, char *errmsg)
4602 {
4603  YRETCODE res;
4604  YDLL_CALL_ENTER(trcHTTPRequestSyncStartOutOfBand);
4605  res = yapiHTTPRequestSyncStartEx_internal(iohdl, channel, device, request, requestsize, reply, replysize, progress_cb, progress_ctx, errmsg);
4606  YDLL_CALL_LEAVE(res);
4607  return res;
4608 }
4609 
4610 
4612 {
4613  YRETCODE res;
4614  YDLL_CALL_ENTER(trcHTTPRequestSyncDone);
4615  res = yapiHTTPRequestSyncDone_internal(iohdl, errmsg);
4616  YDLL_CALL_LEAVE(res);
4617  return res;
4618 }
4619 
4620 YRETCODE YAPI_FUNCTION_EXPORT yapiHTTPRequestAsyncEx(const char *device, const char *request, int len, yapiRequestAsyncCallback callback, void *context, char *errmsg)
4621 {
4622  YRETCODE res;
4623  YDLL_CALL_ENTER(trcHTTPRequestAsyncEx);
4624  res = yapiHTTPRequestAsyncEx_internal(0, device, request, len, callback, context, errmsg);
4625  YDLL_CALL_LEAVE(res);
4626  return res;
4627 }
4628 
4629 YRETCODE YAPI_FUNCTION_EXPORT yapiHTTPRequestAsync(const char *device, const char *request, yapiRequestAsyncCallback callback, void *context, char *errmsg)
4630 {
4631  YRETCODE res;
4632  YDLL_CALL_ENTER(trcHTTPRequestAsync);
4633  res = yapiHTTPRequestAsyncEx_internal(0, device, request, YSTRLEN(request), callback, context, errmsg);
4634  YDLL_CALL_LEAVE(res);
4635  return res;
4636 }
4637 
4638 YRETCODE YAPI_FUNCTION_EXPORT yapiHTTPRequestAsyncOutOfBand(int channel, const char *device, const char *request, int requestsize, yapiRequestAsyncCallback callback, void *context, char *errmsg)
4639 {
4640  YRETCODE res;
4641  YDLL_CALL_ENTER(trcHTTPRequestAsyncOutOfBand);
4642  res = yapiHTTPRequestAsyncEx_internal(channel, device, request, YSTRLEN(request), callback, context, errmsg);
4643  YDLL_CALL_LEAVE(res);
4644  return res;
4645 }
4646 
4647 
4648 int YAPI_FUNCTION_EXPORT yapiHTTPRequest(const char *device, const char *request, char* buffer,int buffsize, int *fullsize, char *errmsg)
4649 {
4650  int res;
4651  YDLL_CALL_ENTER(trcHTTPRequest);
4652  res = yapiHTTPRequest_internal(device, request, buffer, buffsize, fullsize, errmsg);
4653  YDLL_CALL_LEAVE(res);
4654  return res;
4655 }
4656 
4658 {
4659  YDLL_CALL_ENTER(trcRegisterHubDiscoveryCallback);
4660  yapiRegisterHubDiscoveryCallback_internal(hubDiscoveryCallback);
4662 }
4663 
4665 {
4666  YRETCODE res;
4667  YDLL_CALL_ENTER(trcTriggerHubDiscovery);
4668  res = yapiTriggerHubDiscovery_internal(errmsg);
4669  YDLL_CALL_LEAVE(res);
4670  return res;
4671 }
4672 
4673 YRETCODE YAPI_FUNCTION_EXPORT yapiGetBootloaders(char *buffer, int buffersize, int *fullsize, char *errmsg)
4674 {
4675  YRETCODE res;
4676  YDLL_CALL_ENTER(trcGetBootloaders);
4677  res = yapiGetBootloaders_internal(buffer, buffersize, fullsize, errmsg);
4678  YDLL_CALL_LEAVE(res);
4679  return res;
4680 }
4681 #ifndef YAPI_IN_YDEVICE
4682 
4683 int YAPI_FUNCTION_EXPORT yapiJsonDecodeString(const char *json_string, char *output)
4684 {
4685  int res;
4686  YDLL_CALL_ENTER(trcJsonDecodeString);
4687  res = yapiJsonDecodeString_internal(json_string, output);
4688  YDLL_CALL_LEAVE(res);
4689  return res;
4690 }
4691 int YAPI_FUNCTION_EXPORT yapiJsonGetPath(const char *path, const char *json_data, int json_size, const char **result, char *errmsg)
4692 {
4693  int res;
4694  char *tmp;
4695  YDLL_CALL_ENTER(trcJsonGetPath);
4696  res = yapiJsonGetPath_internal(path, json_data, json_size, 0, result, errmsg);
4697  YDLL_CALL_LEAVE(res);
4698  if (res > 0) {
4699  tmp = yMalloc(res);
4700  memcpy(tmp, *result, res);
4701  *result = tmp;
4702  }
4703  return res;
4704 }
4705 
4706 YRETCODE YAPI_FUNCTION_EXPORT yapiGetAllJsonKeys(const char *json_buffer, char *buffer, int buffersize, int *fullsize, char *errmsg)
4707 {
4708  YRETCODE res;
4709  YDLL_CALL_ENTER(trcGetAllJsonKeys);
4710  res = yapiGetAllJsonKeys_internal(json_buffer, buffer, buffersize, fullsize, errmsg);
4711  YDLL_CALL_LEAVE(res);
4712  return res;
4713 }
4714 
4716 {
4717  void *res;
4718  YDLL_CALL_ENTER(trcGetMem);
4719  res = yMalloc(size);
4720  YDLL_CALL_LEAVEPTR(res);
4721  return res;
4722 }
4723 
4725 {
4726  YDLL_CALL_ENTER(trcFreeMem);
4727  yFree(ptr);
4729 }
4730 YRETCODE YAPI_FUNCTION_EXPORT yapiCheckFirmware(const char *serial, const char *rev, const char *path, char *buffer, int buffersize, int *fullsize, char *errmsg)
4731 {
4732  YRETCODE res;
4733  YDLL_CALL_ENTER(trcCheckFirmware);
4734  res = yapiCheckFirmware_internal(serial, rev, 0, path, buffer, buffersize, fullsize, errmsg);
4735  YDLL_CALL_LEAVE(res);
4736  return res;
4737 }
4738 
4739 YRETCODE YAPI_FUNCTION_EXPORT yapiUpdateFirmware(const char *serial, const char *firmwarePath, const char *settings, int startUpdate, char *msg)
4740 {
4741  YRETCODE res;
4742  YDLL_CALL_ENTER(trcUpdateFirmware);
4743  res = yapiUpdateFirmware_internal(serial, firmwarePath, settings, 0, startUpdate, msg);
4744  YDLL_CALL_LEAVE(res);
4745  return res;
4746 }
4747 
4748 YRETCODE YAPI_FUNCTION_EXPORT yapiUpdateFirmwareEx(const char *serial, const char *firmwarePath, const char *settings, int force, int startUpdate, char *msg)
4749 {
4750  YRETCODE res;
4751  YDLL_CALL_ENTER(trcUpdateFirmwareEx);
4752  res = yapiUpdateFirmware_internal(serial, firmwarePath, settings, force, startUpdate, msg);
4753  YDLL_CALL_LEAVE(res);
4754  return res;
4755 }
4756 
4757 
4758 YRETCODE YAPI_FUNCTION_EXPORT yapiGetSubdevices(const char *serial, char *buffer, int buffersize, int *fullsize, char *errmsg)
4759 {
4760  YRETCODE res;
4761  YDLL_CALL_ENTER(trcGetSubdevices);
4762  res = yapiGetSubdevices_internal(serial, buffer, buffersize, fullsize, errmsg);
4763  YDLL_CALL_LEAVE(res);
4764  return res;
4765 }
4766 
4767 #endif
4768 
4769 /*****************************************************************************
4770  Same function but defined with stdcall
4771  ****************************************************************************/
4772 #if defined(WINDOWS_API) && defined(__32BITS__) && defined(_MSC_VER)
4773 
4774 //typedef void YAPI_FUNCTION_EXPORT(_stdcall *vb6_yapiLogFunction)(BSTR log, u32 loglen);
4775 typedef void YAPI_FUNCTION_EXPORT (_stdcall *vb6_yapiDeviceUpdateCallback)(YAPI_DEVICE devdescr);
4776 typedef void YAPI_FUNCTION_EXPORT (_stdcall *vb6_yapiFunctionUpdateCallback)(YAPI_FUNCTION fundescr, BSTR value);
4777 typedef void YAPI_FUNCTION_EXPORT (_stdcall *vb6_yapiTimedReportCallback)(YAPI_FUNCTION fundesc, double timestamp, const u8 *bytes, u32 len);
4778 typedef void YAPI_FUNCTION_EXPORT (_stdcall *vb6_yapiHubDiscoveryCallback)(BSTR serial, BSTR url);
4779 typedef void YAPI_FUNCTION_EXPORT (_stdcall *vb6_yapiDeviceLogCallback)(YAPI_DEVICE devdescr, BSTR line);
4780 typedef void YAPI_FUNCTION_EXPORT (_stdcall *vb6_yapiRequestAsyncCallback)(void *context, int retcode, BSTR result, u32 resultlen);
4781 typedef void YAPI_FUNCTION_EXPORT (_stdcall *vb6_yapiLogFunction)(BSTR log, u32 loglen);
4782 
4783 
4784 typedef struct vb6_callback {
4785  vb6_yapiRequestAsyncCallback callback;
4786  void *context;
4787 } vb_callback_cache_entry;
4788 
4789 static vb_callback_cache_entry vb_callback_cache[NB_MAX_DEVICES];
4790 
4791 
4792 void YAPI_FUNCTION_EXPORT __stdcall vb6_yapiStartStopDeviceLogCallback(const char *serial,int start);
4793 YRETCODE YAPI_FUNCTION_EXPORT __stdcall vb6_yapiInitAPI(int type,char *errmsg);
4794 void YAPI_FUNCTION_EXPORT __stdcall vb6_yapiFreeAPI(void);
4795 //void YAPI_FUNCTION_EXPORT __stdcall vb6_yapiRegisterLogFunction(vb6_yapiLogFunction logfun);
4796 void YAPI_FUNCTION_EXPORT __stdcall vb6_yapiRegisterDeviceLogCallback(vb6_yapiDeviceLogCallback logCallback);
4797 void YAPI_FUNCTION_EXPORT __stdcall vb6_yapiRegisterDeviceArrivalCallback(vb6_yapiDeviceUpdateCallback arrivalCallback);
4798 void YAPI_FUNCTION_EXPORT __stdcall vb6_yapiRegisterDeviceRemovalCallback(vb6_yapiDeviceUpdateCallback removalCallback);
4799 void YAPI_FUNCTION_EXPORT __stdcall vb6_yapiRegisterDeviceChangeCallback(vb6_yapiDeviceUpdateCallback changeCallback);
4800 void YAPI_FUNCTION_EXPORT __stdcall vb6_yapiRegisterFunctionUpdateCallback(vb6_yapiFunctionUpdateCallback updateCallback);
4801 void YAPI_FUNCTION_EXPORT __stdcall vb6_yapiRegisterTimedReportCallback(vb6_yapiTimedReportCallback timedReportCallback);
4802 YRETCODE YAPI_FUNCTION_EXPORT __stdcall vb6_yapiLockFunctionCallBack( char *errmsg);
4803 YRETCODE YAPI_FUNCTION_EXPORT __stdcall vb6_yapiUnlockFunctionCallBack(char *errmsg);
4804 YRETCODE YAPI_FUNCTION_EXPORT __stdcall vb6_yapiLockDeviceCallBack( char *errmsg);
4805 YRETCODE YAPI_FUNCTION_EXPORT __stdcall vb6_yapiUnlockDeviceCallBack(char *errmsg);
4806 YRETCODE YAPI_FUNCTION_EXPORT __stdcall vb6_yapiRegisterHub(const char *rooturl, char *errmsg);
4807 YRETCODE YAPI_FUNCTION_EXPORT __stdcall vb6_yapiPreregisterHub(const char *rooturl, char *errmsg);
4808 void YAPI_FUNCTION_EXPORT __stdcall vb6_yapiUnregisterHub(const char *url);
4809 YRETCODE YAPI_FUNCTION_EXPORT __stdcall vb6_yapiUpdateDeviceList(u32 forceupdate, char *errmsg);
4810 YRETCODE YAPI_FUNCTION_EXPORT __stdcall vb6_yapiHandleEvents(char *errmsg);
4811 YRETCODE YAPI_FUNCTION_EXPORT __stdcall vb6_yapiSleep(int duration_ms, char *errmsg);
4812 u64 YAPI_FUNCTION_EXPORT __stdcall vb6_yapiGetTickCount(void);
4813 int YAPI_FUNCTION_EXPORT __stdcall vb6_yapiCheckLogicalName(const char *name);
4814 u16 YAPI_FUNCTION_EXPORT __stdcall vb6_yapiGetAPIVersion(BSTR *version, BSTR *apidate);
4815 u16 YAPI_FUNCTION_EXPORT __stdcall vb6_yapiGetAPIVersionEx(char *version, char *apidate);
4816 void YAPI_FUNCTION_EXPORT __stdcall vb6_yapiSetTraceFile(const char *file);
4817 YAPI_DEVICE YAPI_FUNCTION_EXPORT __stdcall vb6_yapiGetDevice(const char *device_str,char *errmsg);
4818 int YAPI_FUNCTION_EXPORT __stdcall vb6_yapiGetAllDevices(YAPI_DEVICE *buffer,int maxsize,int *neededsize,char *errmsg);
4819 YRETCODE YAPI_FUNCTION_EXPORT __stdcall vb6_yapiGetDeviceInfo(YAPI_DEVICE devdesc,yDeviceSt *infos,char *errmsg);
4820 YRETCODE YAPI_FUNCTION_EXPORT __stdcall vb6_yapiGetDevicePath(YAPI_DEVICE devdesc, char *rootdevice, char *path, int pathsize, int *neededsize, char *errmsg);
4821 YAPI_FUNCTION YAPI_FUNCTION_EXPORT __stdcall vb6_yapiGetFunction(const char *class_str, const char *function_str,char *errmsg);
4822 int YAPI_FUNCTION_EXPORT __stdcall vb6_yapiGetFunctionsByClass(const char *class_str, YAPI_FUNCTION prevfundesc, YAPI_FUNCTION *buffer,int maxsize,int *neededsize,char *errmsg);
4823 int YAPI_FUNCTION_EXPORT __stdcall vb6_yapiGetFunctionsByDevice(YAPI_DEVICE devdesc, YAPI_FUNCTION prevfundesc, YAPI_FUNCTION *buffer,int maxsize,int *neededsize,char *errmsg);
4824 YRETCODE YAPI_FUNCTION_EXPORT __stdcall vb6_yapiGetFunctionInfo(YAPI_FUNCTION fundesc,YAPI_DEVICE *devdesc,char *serial,char *funcId,char *funcName,char *funcVal,char *errmsg);
4825 YRETCODE YAPI_FUNCTION_EXPORT __stdcall vb6_yapiHTTPRequestSyncStartEx(YIOHDL *iohdl, const char *device, const char *request, int requestsize, char **reply, int *replysize, char *errmsg);
4826 YRETCODE YAPI_FUNCTION_EXPORT __stdcall vb6_yapiHTTPRequestSyncStart(YIOHDL *iohdl, const char *device, const char *request, char **reply, int *replysize, char *errmsg);
4827 YRETCODE YAPI_FUNCTION_EXPORT __stdcall vb6_yapiHTTPRequestSyncDone(YIOHDL *iohdl, char *errmsg);
4828 YRETCODE YAPI_FUNCTION_EXPORT __stdcall vb6_yapiHTTPRequestAsync(const char *device, const char *request, vb6_yapiRequestAsyncCallback callback, void *context, char *errmsg);
4829 YRETCODE YAPI_FUNCTION_EXPORT __stdcall vb6_yapiHTTPRequestAsyncEx(const char *device, const char *request, int requestsize, vb6_yapiRequestAsyncCallback callback, void *context, char *errmsg);
4830 int YAPI_FUNCTION_EXPORT __stdcall vb6_yapiHTTPRequest(const char *device, const char *request, char* buffer,int buffsize,int *fullsize, char *errmsg);
4831 void YAPI_FUNCTION_EXPORT __stdcall vb6_yapiRegisterHubDiscoveryCallback(vb6_yapiHubDiscoveryCallback hubDiscoveryCallback);
4832 YRETCODE YAPI_FUNCTION_EXPORT __stdcall vb6_yapiTriggerHubDiscovery(char *errmsg);
4833 
4834 static BSTR vb6_version = NULL;
4835 static BSTR vb6_apidate = NULL;
4836 
4837 
4838 void YAPI_FUNCTION_EXPORT __stdcall vb6_yapiStartStopDeviceLogCallback(const char *serial,int start)
4839 {
4840  yapiStartStopDeviceLogCallback(serial, start);
4841 }
4842 
4843 YRETCODE YAPI_FUNCTION_EXPORT __stdcall vb6_yapiInitAPI(int type,char *errmsg)
4844 {
4845  return yapiInitAPI(type, errmsg);
4846 }
4847 
4848 void YAPI_FUNCTION_EXPORT __stdcall vb6_yapiFreeAPI(void)
4849 {
4850  yapiFreeAPI();
4851  if (vb6_version) {
4852  SysFreeString(vb6_version);
4853  vb6_version = NULL;
4854  }
4855  if (vb6_apidate) {
4856  SysFreeString(vb6_apidate);
4857  vb6_apidate = NULL;
4858  }
4859 }
4860 
4861 void YAPI_FUNCTION_EXPORT __stdcall vb6_yapiRegisterLogFunction(vb6_yapiLogFunction logfun);
4862 
4863 static BSTR newBSTR(const char * str)
4864 {
4865  int len = YSTRLEN(str);
4866  int newlen = MultiByteToWideChar(CP_ACP, 0, str, len, NULL, 0);
4867  BSTR newstring = SysAllocStringLen(0, newlen);
4868  MultiByteToWideChar(CP_ACP, 0, str, len, newstring, newlen);
4869  return newstring;
4870 }
4871 
4872 // stdcall implementation of yapiRegisterLogFunction
4873 static vb6_yapiLogFunction vb6_yapiLogFunctionFWD = NULL;
4874 void yapiLogFunctionCdeclToStd(const char *log, u32 loglen)
4875 {
4876 
4877  if (vb6_yapiLogFunctionFWD) {
4878  BSTR bstrstr = newBSTR(log);
4879  vb6_yapiLogFunctionFWD(bstrstr, loglen);
4880  SysFreeString(bstrstr);
4881  }
4882 }
4883 void YAPI_FUNCTION_EXPORT __stdcall vb6_yapiRegisterLogFunction(vb6_yapiLogFunction logfun)
4884 {
4885  vb6_yapiLogFunctionFWD = logfun;
4886  if (logfun) {
4887  yapiRegisterLogFunction(yapiLogFunctionCdeclToStd);
4888  } else {
4890  }
4891 }
4892 
4893 
4894 static vb6_yapiDeviceLogCallback vb6_yapiRegisterDeviceLogCallbackFWD = NULL;
4895 void yapiRegisterDeviceLogCallbackFWD(YAPI_DEVICE devdescr, const char *line)
4896 {
4897  if (vb6_yapiRegisterDeviceLogCallbackFWD) {
4898  BSTR bstrstr = newBSTR(line);
4899  vb6_yapiRegisterDeviceLogCallbackFWD(devdescr, bstrstr);
4900  SysFreeString(bstrstr);
4901  }
4902 }
4903 void YAPI_FUNCTION_EXPORT __stdcall vb6_yapiRegisterDeviceLogCallback(vb6_yapiDeviceLogCallback logCallback)
4904 {
4905  vb6_yapiRegisterDeviceLogCallbackFWD = logCallback;
4906  if (logCallback) {
4907  yapiRegisterDeviceLogCallback(yapiRegisterDeviceLogCallbackFWD);
4908  } else {
4910  }
4911 }
4912 
4913 static vb6_yapiDeviceUpdateCallback vb6_yapiRegisterDeviceArrivalCallbackFWD = NULL;
4914 void yapiRegisterDeviceArrivalCallbackFWD(YAPI_DEVICE devdescr)
4915 {
4916  if (vb6_yapiRegisterDeviceArrivalCallbackFWD)
4917  vb6_yapiRegisterDeviceArrivalCallbackFWD(devdescr);
4918 }
4919 void YAPI_FUNCTION_EXPORT __stdcall vb6_yapiRegisterDeviceArrivalCallback(vb6_yapiDeviceUpdateCallback arrivalCallback)
4920 {
4921  vb6_yapiRegisterDeviceArrivalCallbackFWD = arrivalCallback;
4922  if (arrivalCallback) {
4923  yapiRegisterDeviceArrivalCallback(yapiRegisterDeviceArrivalCallbackFWD);
4924  } else {
4926  }
4927 }
4928 
4929 static vb6_yapiDeviceUpdateCallback vb6_yapiRegisterDeviceRemovalCallbackFWD = NULL;
4930 void yapiRegisterDeviceRemovalCallbackFWD(YAPI_DEVICE devdescr)
4931 {
4932  if (vb6_yapiRegisterDeviceRemovalCallbackFWD)
4933  vb6_yapiRegisterDeviceRemovalCallbackFWD(devdescr);
4934 }
4935 
4936 void YAPI_FUNCTION_EXPORT __stdcall vb6_yapiRegisterDeviceRemovalCallback(vb6_yapiDeviceUpdateCallback removalCallback)
4937 {
4938  vb6_yapiRegisterDeviceRemovalCallbackFWD = removalCallback;
4939  if (removalCallback) {
4940  yapiRegisterDeviceRemovalCallback(yapiRegisterDeviceRemovalCallbackFWD);
4941  } else {
4943  }
4944 }
4945 
4946 static vb6_yapiDeviceUpdateCallback vb6_yapiRegisterDeviceChangeCallbackFWD = NULL;
4947 void yapiRegisterDeviceChangeCallbackFWD(YAPI_DEVICE devdescr)
4948 {
4949  if (vb6_yapiRegisterDeviceChangeCallbackFWD)
4950  vb6_yapiRegisterDeviceChangeCallbackFWD(devdescr);
4951 }
4952 void YAPI_FUNCTION_EXPORT __stdcall vb6_yapiRegisterDeviceChangeCallback(vb6_yapiDeviceUpdateCallback changeCallback)
4953 {
4954  vb6_yapiRegisterDeviceChangeCallbackFWD = changeCallback;
4955  if (changeCallback) {
4956  yapiRegisterDeviceChangeCallback(yapiRegisterDeviceChangeCallbackFWD);
4957  } else {
4959  }
4960 }
4961 
4962 static vb6_yapiFunctionUpdateCallback vb6_yapiRegisterFunctionUpdateCallbackFWD = NULL;
4963 void yapiRegisterFunctionUpdateCallbackFWD(YAPI_FUNCTION fundescr, const char *value)
4964 {
4965  if (vb6_yapiRegisterFunctionUpdateCallbackFWD && value) {
4966  BSTR bstrstr = newBSTR(value);
4967  vb6_yapiRegisterFunctionUpdateCallbackFWD(fundescr, bstrstr);
4968  SysFreeString(bstrstr);
4969  }
4970 }
4971 void YAPI_FUNCTION_EXPORT __stdcall vb6_yapiRegisterFunctionUpdateCallback(vb6_yapiFunctionUpdateCallback updateCallback)
4972 {
4973  vb6_yapiRegisterFunctionUpdateCallbackFWD = updateCallback;
4974  if (updateCallback) {
4975  yapiRegisterFunctionUpdateCallback(yapiRegisterFunctionUpdateCallbackFWD);
4976  } else {
4978  }
4979 }
4980 
4981 static vb6_yapiTimedReportCallback vb6_yapiRegisterTimedReportCallbackFWD = NULL;
4982 void yapiRegisterTimedReportCallbackFWD(YAPI_FUNCTION fundesc, double timestamp, const u8 *bytes, u32 len)
4983 {
4984  if (vb6_yapiRegisterTimedReportCallbackFWD)
4985  vb6_yapiRegisterTimedReportCallbackFWD(fundesc, timestamp, bytes, len);
4986 }
4987 
4988 void YAPI_FUNCTION_EXPORT __stdcall vb6_yapiRegisterTimedReportCallback(vb6_yapiTimedReportCallback timedReportCallback)
4989 {
4990  vb6_yapiRegisterTimedReportCallbackFWD = timedReportCallback;
4991  if (timedReportCallback) {
4992  yapiRegisterTimedReportCallback(yapiRegisterTimedReportCallbackFWD);
4993  } else {
4995  }
4996 }
4997 
4998 YRETCODE YAPI_FUNCTION_EXPORT __stdcall vb6_yapiLockFunctionCallBack(char *errmsg)
4999 {
5000  return yapiLockFunctionCallBack(errmsg);
5001 }
5002 
5003 YRETCODE YAPI_FUNCTION_EXPORT __stdcall vb6_yapiUnlockFunctionCallBack(char *errmsg)
5004 {
5005  return yapiUnlockFunctionCallBack(errmsg);
5006 }
5007 
5008 YRETCODE YAPI_FUNCTION_EXPORT __stdcall vb6_yapiLockDeviceCallBack(char *errmsg)
5009 {
5010  return yapiLockDeviceCallBack(errmsg);
5011 }
5012 
5013 YRETCODE YAPI_FUNCTION_EXPORT __stdcall vb6_yapiUnlockDeviceCallBack(char *errmsg)
5014 {
5015  return yapiUnlockDeviceCallBack(errmsg);
5016 }
5017 
5018 YRETCODE YAPI_FUNCTION_EXPORT __stdcall vb6_yapiRegisterHub(const char *rooturl, char *errmsg)
5019 {
5020  return yapiRegisterHub(rooturl, errmsg);
5021 }
5022 
5023 YRETCODE YAPI_FUNCTION_EXPORT __stdcall vb6_yapiPreregisterHub(const char *rooturl, char *errmsg)
5024 {
5025  return yapiPreregisterHub(rooturl, errmsg);
5026 }
5027 
5028 void YAPI_FUNCTION_EXPORT __stdcall vb6_yapiUnregisterHub(const char *url)
5029 {
5030  yapiUnregisterHub(url);
5031 }
5032 
5033 YRETCODE YAPI_FUNCTION_EXPORT __stdcall vb6_yapiUpdateDeviceList(u32 forceupdate, char *errmsg)
5034 {
5035  return yapiUpdateDeviceList(forceupdate, errmsg);
5036 }
5037 
5038 YRETCODE YAPI_FUNCTION_EXPORT __stdcall vb6_yapiHandleEvents(char *errmsg)
5039 {
5040  return yapiHandleEvents(errmsg);
5041 }
5042 
5043 YRETCODE YAPI_FUNCTION_EXPORT __stdcall vb6_yapiSleep(int duration_ms, char *errmsg)
5044 {
5045  return yapiSleep(duration_ms, errmsg);
5046 }
5047 
5048 u64 YAPI_FUNCTION_EXPORT __stdcall vb6_yapiGetTickCount(void)
5049 {
5050  return yapiGetTickCount();
5051 }
5052 
5053 int YAPI_FUNCTION_EXPORT __stdcall vb6_yapiCheckLogicalName(const char *name)
5054 {
5055  return yapiCheckLogicalName(name);
5056 }
5057 
5058 u16 YAPI_FUNCTION_EXPORT __stdcall vb6_yapiGetAPIVersion(BSTR *version, BSTR *apidate)
5059 {
5060  const char * versionA, *apidateA;
5061  u16 res = yapiGetAPIVersion(&versionA, &apidateA);
5062  *version = newBSTR(versionA);
5063  *apidate = newBSTR(apidateA);
5064  return res;
5065 }
5066 
5067 u16 YAPI_FUNCTION_EXPORT __stdcall vb6_yapiGetAPIVersionEx(char *version, char *apidate)
5068 {
5069  const char * versionA, *apidateA;
5070  u16 res = yapiGetAPIVersion(&versionA, &apidateA);
5071  YSTRCPY(version, YOCTO_ERRMSG_LEN, versionA);
5072  YSTRCPY(apidate, YOCTO_ERRMSG_LEN, apidateA);
5073  return res;
5074 }
5075 
5076 
5077 void YAPI_FUNCTION_EXPORT __stdcall vb6_yapiSetTraceFile(const char *file)
5078 {
5079  yapiSetTraceFile(file);
5080 }
5081 
5082 YAPI_DEVICE YAPI_FUNCTION_EXPORT __stdcall vb6_yapiGetDevice(const char *device_str,char *errmsg)
5083 {
5084  return yapiGetDevice(device_str, errmsg);
5085 }
5086 
5087 int YAPI_FUNCTION_EXPORT __stdcall vb6_yapiGetAllDevices(YAPI_DEVICE *buffer, int maxsize, int *neededsize, char *errmsg)
5088 {
5089  return yapiGetAllDevices(buffer, maxsize, neededsize, errmsg);
5090 }
5091 
5092 YRETCODE YAPI_FUNCTION_EXPORT __stdcall vb6_yapiGetDeviceInfo(YAPI_DEVICE devdesc, yDeviceSt *infos, char *errmsg)
5093 {
5094  return yapiGetDeviceInfo(devdesc, infos, errmsg);
5095 }
5096 
5097 YRETCODE YAPI_FUNCTION_EXPORT __stdcall vb6_yapiGetDevicePath(YAPI_DEVICE devdesc, char *rootdevice, char *path, int pathsize, int *neededsize, char *errmsg)
5098 {
5099  return yapiGetDevicePath(devdesc, rootdevice, path, pathsize, neededsize, errmsg);
5100 }
5101 
5102 YAPI_FUNCTION YAPI_FUNCTION_EXPORT __stdcall vb6_yapiGetFunction(const char *class_str, const char *function_str,char *errmsg)
5103 {
5104  return yapiGetFunction(class_str, function_str, errmsg);
5105 }
5106 
5107 int YAPI_FUNCTION_EXPORT __stdcall vb6_yapiGetFunctionsByClass(const char *class_str, YAPI_FUNCTION prevfundesc, YAPI_FUNCTION *buffer, int maxsize, int *neededsize, char *errmsg)
5108 {
5109  return yapiGetFunctionsByClass(class_str, prevfundesc, buffer, maxsize, neededsize, errmsg);
5110 }
5111 
5112 int YAPI_FUNCTION_EXPORT __stdcall vb6_yapiGetFunctionsByDevice(YAPI_DEVICE devdesc, YAPI_FUNCTION prevfundesc, YAPI_FUNCTION *buffer,int maxsize,int *neededsize,char *errmsg)
5113 {
5114  return yapiGetFunctionsByDevice(devdesc, prevfundesc, buffer, maxsize, neededsize, errmsg);
5115 }
5116 
5117 YRETCODE YAPI_FUNCTION_EXPORT __stdcall vb6_yapiGetFunctionInfo(YAPI_FUNCTION fundesc,YAPI_DEVICE *devdesc,char *serial,char *funcId,char *funcName,char *funcVal,char *errmsg)
5118 {
5119  return yapiGetFunctionInfo(fundesc, devdesc, serial, funcId, funcName, funcVal, errmsg);
5120 }
5121 
5122 YRETCODE YAPI_FUNCTION_EXPORT __stdcall vb6_yapiHTTPRequestSyncStartEx(YIOHDL *iohdl, const char *device, const char *request, int requestsize, char **reply, int *replysize, char *errmsg)
5123 {
5124  return yapiHTTPRequestSyncStartEx(iohdl, device, request, requestsize, reply, replysize, errmsg);
5125 }
5126 
5127 YRETCODE YAPI_FUNCTION_EXPORT __stdcall vb6_yapiHTTPRequestSyncStart(YIOHDL *iohdl, const char *device, const char *request, char **reply, int *replysize, char *errmsg)
5128 {
5129  return yapiHTTPRequestSyncStart(iohdl, device, request, reply, replysize, errmsg);
5130 }
5131 
5132 YRETCODE YAPI_FUNCTION_EXPORT __stdcall vb6_yapiHTTPRequestSyncDone(YIOHDL *iohdl, char *errmsg)
5133 {
5134  return yapiHTTPRequestSyncDone(iohdl, errmsg);
5135 }
5136 
5137 YRETCODE YAPI_FUNCTION_EXPORT __stdcall vb6_yapiHTTPRequestAsync(const char *device, const char *request, vb6_yapiRequestAsyncCallback callback, void *context, char *errmsg)
5138 {
5139  return vb6_yapiHTTPRequestAsyncEx(device, request, YSTRLEN(request), callback, context, errmsg);
5140 }
5141 
5142 static void vb6_callback_fwd(void *context, const u8 *result, u32 resultlen, int retcode, const char *errmsg)
5143 {
5144  YAPI_DEVICE devydx = (YAPI_DEVICE) context;
5145  void *vb6_context = vb_callback_cache[devydx].context;
5146  BSTR bstrstr = newBSTR((char*) result);
5147  vb_callback_cache[devydx].callback(vb6_context, retcode, bstrstr, resultlen);
5148  SysFreeString(bstrstr);
5149 }
5150 
5151 
5152 YRETCODE YAPI_FUNCTION_EXPORT __stdcall vb6_yapiHTTPRequestAsyncEx(const char *device, const char *request, int requestsize, vb6_yapiRequestAsyncCallback callback, void *context, char *errmsg)
5153 {
5154  YAPI_DEVICE devydx = wpSearch(device);
5155  vb_callback_cache[devydx].callback = callback;
5156  vb_callback_cache[devydx].context = context;
5157  return yapiHTTPRequestAsyncEx(device, request, requestsize, vb6_callback_fwd, (void*)devydx, errmsg);
5158 }
5159 
5160 int YAPI_FUNCTION_EXPORT __stdcall vb6_yapiHTTPRequest(const char *device, const char *request, char* buffer, int buffsize, int *fullsize, char *errmsg)
5161 {
5162  return yapiHTTPRequest(device, request, buffer, buffsize, fullsize, errmsg);
5163 }
5164 
5165 static vb6_yapiHubDiscoveryCallback vb6_yapiHubDiscoveryCallbackFWD = NULL;
5166 void yapiHubDiscoverCdeclToStdllbackFWD(const char *serial, const char *url)
5167 {
5168  if (vb6_yapiHubDiscoveryCallbackFWD) {
5169  BSTR bstrserial = newBSTR(serial);
5170  BSTR bstrurl = newBSTR(url);
5171  vb6_yapiHubDiscoveryCallbackFWD(bstrserial, bstrurl);
5172  SysFreeString(bstrurl);
5173  SysFreeString(bstrserial);
5174  }
5175 }
5176 void YAPI_FUNCTION_EXPORT __stdcall vb6_yapiRegisterHubDiscoveryCallback(vb6_yapiHubDiscoveryCallback hubDiscoveryCallback)
5177 {
5178  vb6_yapiHubDiscoveryCallbackFWD = hubDiscoveryCallback;
5179  if (hubDiscoveryCallback){
5180  yapiRegisterHubDiscoveryCallback(yapiHubDiscoverCdeclToStdllbackFWD);
5181  } else {
5183  }
5184 }
5185 
5186 YRETCODE YAPI_FUNCTION_EXPORT __stdcall vb6_yapiTriggerHubDiscovery(char *errmsg)
5187 {
5188  return yapiTriggerHubDiscovery(errmsg);
5189 }
5190 
5191 
5192 #endif
5193 
_FAR const char * state_start
Definition: yjson.h:93
static YRETCODE yapiGetDeviceInfo_internal(YAPI_DEVICE devdesc, yDeviceSt *infos, char *errmsg)
Definition: yapi.c:2884
yUrlRef url
Definition: yproto.h:799
#define yMemset(dst, val, size)
Definition: yproto.h:203
d
static int yNetHubEnum(HubSt *hub, int forceupdate, char *errmsg)
Definition: yapi.c:1088
int yUsbReadBlock(YIOHDL_internal *ioghdl, char *buffer, int len, u64 blockUntil, char *errmsg)
Definition: ystream.c:2728
int yUsbOpen(YIOHDL_internal *ioghdl, const char *device, char *errmsg)
Definition: ystream.c:2566
yStrRef wpGetAttribute(yBlkHdl hdl, yWPAttribute attridx)
Definition: yhash.c:880
static fullAttrInfo * parseSettings(const char *settings, int *count)
Definition: yapi.c:3951
YAPI_FUNCTION YAPI_FUNCTION_EXPORT yapiGetFunction(const char *class_str, const char *function_str, char *errmsg)
Definition: yapi.c:4533
#define NBMAX_NET_HUB
Definition: yproto.h:553
static YAPI_DEVICE yapiGetDevice_internal(const char *device_str, char *errmsg)
Definition: yapi.c:2819
void yThreadKill(yThread *yth)
Definition: ythread.c:343
#define YDLL_CALL_LEAVEVOID()
Definition: yapi.c:4289
int rw_access
Definition: yproto.h:801
int handleNetNotification(HubSt *hub)
Definition: yapi.c:1677
HubSt * nethub[NBMAX_NET_HUB]
Definition: yproto.h:941
#define YOCTO_API_VERSION_BCD
Definition: ydef.h:398
static YAPI_FUNCTION yapiGetFunction_internal(const char *class_str, const char *function_str, char *errmsg)
Definition: yapi.c:2979
#define NOTIFY_NETPKT_START_LEN
Definition: ydef.h:693
YRETCODE YAPI_FUNCTION_EXPORT yapiGetFunctionInfo(YAPI_FUNCTION fundesc, YAPI_DEVICE *devdesc, char *serial, char *funcId, char *funcName, char *funcVal, char *errmsg)
Definition: yapi.c:4562
int decodeNetFuncValV2(const u8 *p, Notification_funydx *funInfo, char *funcVal)
Definition: yhash.c:2056
YRETCODE YAPI_FUNCTION_EXPORT yapiTestHub(const char *url, int mstimeout, char *errmsg)
Definition: yapi.c:4403
int mandatory
Definition: yproto.h:803
int yUsbEOF(YIOHDL_internal *ioghdl, char *errmsg)
Definition: ystream.c:2771
static void yapiRegisterDeviceLogCallback_internal(yapiDeviceLogCallback logCallback)
Definition: yapi.c:1511
#define ySafeMemoryStop()
Definition: ymemory.h:54
int yWaitForEvent(yEvent *ev, int time)
Definition: ythread.c:196
#define YERRMSG(code, message)
Definition: yproto.h:458
#define YSTRREF_EMPTY_STRING
Definition: yhash.h:62
yCRITICAL_SECTION access
Definition: yproto.h:821
#define YDLL_CALL_LEAVEPTR(value)
Definition: yapi.c:4291
void YAPI_FUNCTION_EXPORT(* yapiDeviceUpdateCallback)(YAPI_DEVICE devdescr)
Definition: yapi.h:68
int ypGetFunctions(const char *class_str, YAPI_DEVICE devdesc, YAPI_FUNCTION prevfundesc, YAPI_FUNCTION *buffer, int maxsize, int *neededsize)
Definition: yhash.c:1763
int yHashSameHub(yUrlRef url_a, yUrlRef url_b)
Definition: yhash.c:619
static YRETCODE yapiGetFunctionInfoEx_internal(YAPI_FUNCTION fundesc, YAPI_DEVICE *devdesc, char *serial, char *funcId, char *baseType, char *funcName, char *funcVal, char *errmsg)
Definition: yapi.c:3031
void * ws_thread(void *ctx)
Definition: ytcp.c:2537
static const char * yapiJsonValueParseStruct(yJsonStateMachine *j, const char *path, int *result, char *errmsg)
Definition: yapi.c:3762
u64 lastTraffic
Definition: yproto.h:739
YIOHDL_internal * yiohdl_first
Definition: yproto.h:938
s16 yHash
Definition: ydef.h:212
#define NOTIFY_NETPKT_DEVLOGYDX
Definition: ydef.h:685
void ypUpdateUSB(const char *serial, const char *funcid, const char *funcname, int funclass, int funydx, const char *funcval)
Definition: ystream.c:255
void yReqFree(struct _RequestSt *req)
Definition: ytcp.c:1606
u64 attemptDelay
Definition: yproto.h:816
void yCreateEvent(yEvent *ev)
Definition: ythread.c:159
#define YSTRICMP(A, B)
Definition: yproto.h:228
static int yNetHubEnumEx(HubSt *hub, ENU_CONTEXT *enus, char *errmsg)
Definition: yapi.c:1004
static int yapiCheckLogicalName_internal(const char *name)
Definition: yapi.c:2779
ROSCPP_DECL void start()
#define NOTIFY_NETPKT_TIMEAVGYDX
Definition: ydef.h:688
#define NOTIFY_NETPKT_FUNCVAL
Definition: ydef.h:677
Definition: ykey.h:74
static void ypUpdateNet(ENU_CONTEXT *enus)
Definition: yapi.c:754
void * YIOHDL
Definition: ydef.h:260
void yInitializeCriticalSection(yCRITICAL_SECTION *cs)
Definition: ythread.c:629
#define YERRMSGSILENT(code, message)
Definition: yproto.h:459
void yFifoCleanup(yFifoBuf *buf)
Definition: yfifo.c:70
int yReqIsAsync(struct _RequestSt *req)
Definition: ytcp.c:1596
u64 devListExpires
Definition: yproto.h:817
s32 YAPI_FUNCTION
Definition: ydef.h:217
int yReqSelect(struct _RequestSt *tcpreq, u64 ms, char *errmsg)
Definition: ytcp.c:1470
yHash yStrRef
Definition: ydef.h:214
YRETCODE YAPI_FUNCTION_EXPORT yapiGetBootloaders(char *buffer, int buffersize, int *fullsize, char *errmsg)
Definition: yapi.c:4673
static void yapiRegisterDeviceChangeCallback_internal(yapiDeviceUpdateCallback changeCallback)
Definition: yapi.c:1587
int ySSDPDiscover(SSDPInfos *SSDP, char *errmsg)
Definition: ytcp.c:3233
f
void YAPI_FUNCTION_EXPORT yapiRegisterDeviceLogCallback(yapiDeviceLogCallback logCallback)
Definition: yapi.c:4318
#define YOCTO_DEVID_BOOTLOADER
Definition: ydef.h:404
static void yapiRegisterTimedReportCallback_internal(yapiTimedReportCallback timedReportCallback)
Definition: yapi.c:1610
static const char * yapiJsonValueParseArray(yJsonStateMachine *j, const char *path, int *result, char *errmsg)
Definition: yapi.c:3835
yHash yUrlRef
Definition: ydef.h:215
void yUSBReleaseAllDevices(void)
Definition: ystream.c:2182
static int wpSafeCheckOverwrite(yUrlRef registeredUrl, HubSt *hub, yUrlRef devUrl)
Definition: yapi.c:341
void yFunctionTimedUpdate(YAPI_FUNCTION fundescr, double deviceTime, const u8 *report, u32 len)
Definition: yapi.c:237
yStrRef serial
Definition: yproto.h:805
YRETCODE YAPI_FUNCTION_EXPORT yapiGetDevicePath(YAPI_DEVICE devdesc, char *rootdevice, char *request, int requestsize, int *neededsize, char *errmsg)
Definition: yapi.c:4515
int yReqGet(struct _RequestSt *req, u8 **buffer)
Definition: ytcp.c:1504
yCRITICAL_SECTION handleEv_cs
Definition: yproto.h:925
int yStartWakeUpSocket(WakeUpSocket *wuce, char *errmsg)
Definition: ytcp.c:225
u16 yPushFifo(yFifoBuf *buf, const u8 *data, u16 datalen)
Definition: yfifo.c:143
static int yapiRequestWaitEndWS(YIOHDL_internal *iohdl, char **reply, int *replysize, char *errmsg)
Definition: yapi.c:3322
static YRETCODE yapiHandleEvents_internal(char *errmsg)
Definition: yapi.c:2664
int yReqRead(struct _RequestSt *req, u8 *buffer, int len)
Definition: ytcp.c:1525
char advertisedValue[YOCTO_PUBVAL_LEN]
Definition: yapi.c:330
void yHashGetStr(yHash yhash, char *destbuf, u16 bufsize)
Definition: yhash.c:365
u16 yPeekFifo(yFifoBuf *buf, u8 *data, u16 datalen, u16 startofs)
Definition: yfifo.c:263
void YAPI_FUNCTION_EXPORT yapiRegisterTimedReportCallback(yapiTimedReportCallback timedReportCallback)
Definition: yapi.c:4360
yapiDeviceUpdateCallback arrivalCallback
Definition: yproto.h:953
void yapiRegisterRawReportV2Cb(yRawReportV2Cb callback)
Definition: yapi.c:4113
int yUsbClose(YIOHDL_internal *ioghdl, char *errmsg)
Definition: ystream.c:2811
#define YAPI_BLOCKING_USBOPEN_REQUEST_TIMEOUT
Definition: yapi.h:56
u16 productId
Definition: yapi.c:322
yAsbUrlType
Definition: yhash.h:173
u16 wpEntryCount(void)
Definition: yhash.c:963
int ypRegisterByYdx(u8 devYdx, Notification_funydx funInfo, const char *funcVal, YAPI_FUNCTION *fundesc)
Definition: yhash.c:1395
#define wpAllowUnregister()
Definition: yhash.h:244
static void unregisterNetDevice(yStrRef serialref)
Definition: yapi.c:740
XmlRpcServer s
#define YIO_1_MINUTE_TCP_TIMEOUT
Definition: ydef.h:251
static u16 yapiGetAPIVersion_internal(const char **version, const char **apidate)
Definition: yapi.c:2798
yDeviceSt infos
Definition: yproto.h:689
#define YSTRCAT(dst, dstsize, src)
Definition: yproto.h:235
int yUsbFree(yContextSt *ctx, char *errmsg)
Definition: ystream.c:2410
char token[62]
Definition: yjson.h:88
yContextSt * yContext
Definition: ystream.c:59
#define yFifoInit(fifo, buffer, len)
Definition: yfifo.h:84
char manufacturer[YOCTO_MANUFACTURER_LEN]
Definition: ydef.h:452
static void yapiRegisterDeviceArrivalCallback_internal(yapiDeviceUpdateCallback arrivalCallback)
Definition: yapi.c:1543
#define HASH_BUF_SIZE
Definition: yhash.h:52
static void yapiUnregisterHub_internal(const char *url)
Definition: yapi.c:2591
static void yapiRegisterDeviceRemovalCallback_internal(yapiDeviceUpdateCallback removalCallback)
Definition: yapi.c:1573
static HubSt * yapiAllocHub(const char *url, char *errmsg)
Definition: yapi.c:1153
void(* RequestProgress)(void *context, u32 acked, u32 totalbytes)
Definition: yproto.h:855
void(* yapiRequestProgressCallback)(void *context, u32 acked, u32 totalbytes)
Definition: ydef.h:866
#define YSTRREF_mODULE_STRING
Definition: yhash.h:64
int yThreadCreate(yThread *yth, void *(*fun)(void *), void *arg)
Definition: ythread.c:293
const int Y_DETECT_USB
Definition: yocto_api.h:204
#define NOTIFY_NETPKT_SEP
Definition: ydef.h:695
int YAPI_FUNCTION_EXPORT yapiJsonDecodeString(const char *json_string, char *output)
Definition: yapi.c:4683
int yNetHubGetBootloaders(const char *hubserial, char *buffer, char *errmsg)
Definition: yprog.c:1420
static YRETCODE yapiHTTPRequestAsyncEx_internal(int tcpchan, const char *device, const char *request, int len, yapiRequestAsyncCallback callback, void *context, char *errmsg)
Definition: yapi.c:3455
int yReqMultiSelect(struct _RequestSt **tcpreq, int size, u64 ms, WakeUpSocket *wuce, char *errmsg)
Definition: ytcp.c:1479
#define YOCTO_FIRMWARE_LEN
Definition: ydef.h:423
#define YERR(code)
Definition: yproto.h:456
yapiFunctionUpdateCallback functionCallback
Definition: yproto.h:956
#define dbglog(args...)
Definition: yproto.h:413
char * s_realm
Definition: yproto.h:742
#define DEVGEN_LOG_ACTIVATED
Definition: yproto.h:646
void devHdlInfo(YUSBDEV hdl, yDeviceSt *infos)
Definition: ystream.c:2334
yPrivDeviceSt * findDevFromIOHdl(YIOHDL_internal *hdl)
Definition: ystream.c:2310
#define NOTIFY_NETPKT_START
Definition: ydef.h:692
struct _fullAttrInfo fullAttrInfo
u16 yFifoGetUsed(yFifoBuf *buf)
Definition: yfifo.c:385
static YRETCODE yapiTriggerHubDiscovery_internal(char *errmsg)
Definition: yapi.c:3530
#define NOTIFY_NETPKT_TIMEVALYDX
Definition: ydef.h:686
#define YPROPERR(call)
Definition: yproto.h:455
static void * yhelper_thread(void *ctx)
Definition: yapi.c:2069
u32 yapiGetCNonce(u32 nc)
Definition: yapi.c:2750
yJsonState next
Definition: yjson.h:85
yRawReportV2Cb rawReportV2Cb
Definition: yproto.h:945
int ySetErr(int code, char *outmsg, const char *erreur, const char *file, u32 line)
Definition: ystream.c:72
int writeProtected
Definition: yproto.h:804
void yHashInit(void)
Definition: yhash.c:189
yJsonRetCode yJsonParse(yJsonStateMachine *j)
Definition: yjson.c:83
_FAR const char * src
Definition: yjson.h:82
int yyyUSBGetInterfaces(yInterfaceSt **ifaces, int *nbifaceDetect, char *errmsg)
yAsbUrlType yHashGetUrlPort(yUrlRef urlref, char *url, u16 *port, yAsbUrlProto *proto, yStrRef *user, yStrRef *password)
Definition: yhash.c:579
static int yEnuJson(ENU_CONTEXT *enus, yJsonStateMachine *j)
Definition: yapi.c:763
int wpGetDevYdx(yStrRef serial)
Definition: yhash.c:968
#define YOCTO_SERIAL_LEN
Definition: ydef.h:420
void yLeaveCriticalSection(yCRITICAL_SECTION *cs)
Definition: ythread.c:672
void YAPI_FUNCTION_EXPORT yapiFreeAPI(void)
Definition: yapi.c:4304
void yProgInit(void)
Definition: yprog.c:76
yCRITICAL_SECTION functionCallbackCS
Definition: yproto.h:947
YRETCODE YAPI_FUNCTION_EXPORT yapiLockFunctionCallBack(char *errmsg)
Definition: yapi.c:4367
YRETCODE yapiRequestOpen(YIOHDL_internal *iohdl, int tcpchan, const char *device, const char *request, int reqlen, yapiRequestAsyncCallback callback, void *context, yapiRequestProgressCallback progress_cb, void *progress_ctx, char *errmsg)
Definition: yapi.c:3189
#define NOTIFY_NETPKT_STOP
Definition: ydef.h:694
#define YOCTO_ERRMSG_LEN
Definition: ydef.h:418
void wpSafeUnregister(yStrRef serialref)
Definition: yapi.c:703
u8 funClass
Definition: yapi.c:331
yStrRef logicalName
Definition: yapi.c:318
Definition: yproto.h:798
#define NOTIFY_NETPKT_FLUSHV2YDX
Definition: ydef.h:682
s8 beacon
Definition: yapi.c:324
char * yHashGetStrPtr(yHash yhash)
Definition: yhash.c:401
static void yapiRegisterFunctionUpdateCallback_internal(yapiFunctionUpdateCallback updateCallback)
Definition: yapi.c:1599
int retryCount
Definition: yproto.h:813
void yHashFree(void)
Definition: yhash.c:240
int YAPI_FUNCTION_EXPORT yapiGetAllDevices(YAPI_DEVICE *buffer, int maxsize, int *neededsize, char *errmsg)
Definition: yapi.c:4497
int yDringWakeUpSocket(WakeUpSocket *wuce, u8 signal, char *errmsg)
Definition: ytcp.c:263
YRETCODE yapiPullDeviceLog(const char *serial)
Definition: yapi.c:563
void yJsonSkip(yJsonStateMachine *j, int nitems)
Definition: yjson.c:367
#define YDLL_CALL_ENTER(funname)
Definition: yapi.c:4288
YRETCODE YAPI_FUNCTION_EXPORT yapiHTTPRequestSyncStartEx(YIOHDL *iohdl, const char *device, const char *request, int requestsize, char **reply, int *replysize, char *errmsg)
Definition: yapi.c:4582
#define NOTIFY_NETPKT_FUNCNAME
Definition: ydef.h:676
#define YAPI_BLOCKING_USBREAD_REQUEST_TIMEOUT
Definition: yapi.h:57
void yProgFree(void)
Definition: yprog.c:88
#define NOTIFY_NETPKT_NOT_SYNC
Definition: ydef.h:689
#define YOCTO_PUBVAL_LEN
Definition: ydef.h:428
#define LOCALURL_LEN
char ytracefile[]
Definition: ystream.c:64
#define NET_HUB_NOT_CONNECTION_TIMEOUT
Definition: yproto.h:733
u32 notifAbsPos
Definition: yproto.h:814
yCRITICAL_SECTION deviceCallbackCS
Definition: yproto.h:946
int yReqOpen(struct _RequestSt *req, int wait_for_start, int tcpchan, const char *request, int reqlen, u64 mstimeout, yapiRequestAsyncCallback callback, void *context, RequestProgress progress_cb, void *progress_ctx, char *errmsg)
Definition: ytcp.c:1362
YRETCODE yapiGetBootloadersDevs(char *serials, unsigned int maxNbSerial, unsigned int *totalBootladers, char *errmsg)
Definition: yapi.c:3541
YRETCODE
Definition: ydef.h:376
void ySSDPStop(SSDPInfos *SSDP)
Definition: ytcp.c:3330
yCRITICAL_SECTION io_cs
Definition: yproto.h:937
int yUsbSetIOAsync(YIOHDL_internal *ioghdl, yapiRequestAsyncCallback callback, void *context, char *errmsg)
Definition: ystream.c:2602
HubSt * hub
Definition: yproto.h:859
void yFreeWakeUpSocket(WakeUpSocket *wuce)
Definition: ytcp.c:281
YAPI_DEVICE YAPI_FUNCTION_EXPORT yapiGetDevice(const char *device_str, char *errmsg)
Definition: yapi.c:4488
#define YIOHDL_SIZE
Definition: ydef.h:263
int yUsbIdle(void)
Definition: ystream.c:2441
void MD5Calculate(HASH_SUM *ctx, u8 digest[16])
Definition: ykey.c:671
int YAPI_FUNCTION_EXPORT yapiCheckLogicalName(const char *name)
Definition: yapi.c:4464
yStrRef funcId
Definition: yapi.c:329
static int yapiGetAllDevices_internal(YAPI_DEVICE *buffer, int maxsize, int *neededsize, char *errmsg)
Definition: yapi.c:2846
static void unregisterNetHub(yUrlRef huburl)
Definition: yapi.c:1224
int wpGetDeviceUrl(YAPI_DEVICE devdesc, char *roothubserial, char *request, int requestsize, int *neededsize)
Definition: yhash.c:1124
NET_HUB_STATE state
Definition: yproto.h:810
static YRETCODE yapiLockDeviceCallBack_internal(char *errmsg)
Definition: yapi.c:2284
_FAR const char * end
Definition: yjson.h:83
yAsbUrlProto proto
Definition: yproto.h:809
u16 vendorid
Definition: ydef.h:448
#define YIO_10_MINUTES_TCP_TIMEOUT
Definition: ydef.h:252
u16 deviceid
Definition: ydef.h:449
yapiTimedReportCallback timedReportCallback
Definition: yproto.h:957
void YAPI_FUNCTION_EXPORT yapiRegisterLogFunction(yapiLogFunction logfun)
Definition: yapi.c:4311
void yThreadRequestEnd(yThread *yth)
Definition: ythread.c:331
#define yApproximateSleep(ms)
Definition: yproto.h:433
void * ctx
Definition: ythread.h:96
int wpGetAllDevUsingHubUrl(yUrlRef hubUrl, yStrRef *buffer, int sizeInStrRef)
Definition: yhash.c:1072
YRETCODE YAPI_FUNCTION_EXPORT yapiUpdateFirmware(const char *serial, const char *firmwarePath, const char *settings, int startUpdate, char *msg)
Definition: yapi.c:4739
static YRETCODE yapiUnlockFunctionCallBack_internal(char *errmsg)
Definition: yapi.c:2275
void freeDevYdxInfos(int devYdx)
Definition: yapi.c:388
struct Notification_funydx::@10 v2
static YRETCODE yapiInitAPI_internal(int detect_type, char *errmsg)
Definition: yapi.c:1331
static void ssdpEntryUpdate(const char *serial, const char *urlToRegister, const char *urlToUnregister)
Definition: yapi.c:1265
int nbKnownDevices
Definition: yapi.c:335
#define INVALID_BLK_HDL
Definition: ydef.h:220
static int yapiRequestWaitEndUSB(YIOHDL_internal *iohdl, char **reply, int *replysize, char *errmsg)
Definition: yapi.c:3252
#define YSTRCPY(dst, dstsize, src)
Definition: yproto.h:234
void YAPI_FUNCTION_EXPORT(* yapiTimedReportCallback)(YAPI_FUNCTION fundesc, double timestamp, const u8 *bytes, u32 len)
Definition: yapi.h:78
static YRETCODE yapiGetDevicePathEx_internal(const char *serial, char *rootdevice, char *request, int requestsize, int *neededsize, char *errmsg)
Definition: yapi.c:2933
#define NOTIFY_NETPKT_CHILD
Definition: ydef.h:674
#define YOCTO_PUBVAL_SIZE
Definition: ydef.h:427
static void yapiRegisterHubDiscoveryCallback_internal(yapiHubDiscoveryCallback hubDiscoveryCallback)
Definition: yapi.c:3519
int YAPI_FUNCTION_EXPORT yapiGetFunctionsByClass(const char *class_str, YAPI_FUNCTION prevfundesc, YAPI_FUNCTION *buffer, int maxsize, int *neededsize, char *errmsg)
Definition: yapi.c:4542
static int yapiRequestOpenUSB(YIOHDL_internal *iohdl, HubSt *hub, YAPI_DEVICE dev, const char *request, int reqlen, u64 unused_timeout, yapiRequestAsyncCallback callback, void *context, char *errmsg)
Definition: yapi.c:3046
int ySSDPStart(SSDPInfos *SSDP, ssdpHubDiscoveryCallback callback, char *errmsg)
Definition: ytcp.c:3253
char * name
Definition: yproto.h:808
yCRITICAL_SECTION updateDev_cs
Definition: yproto.h:924
char * s_opaque
Definition: yproto.h:745
yStrRef productName
Definition: yapi.c:321
u64 lastAttempt
Definition: yproto.h:815
WSNetHub ws
Definition: yproto.h:824
void YAPI_FUNCTION_EXPORT yapiRegisterHubDiscoveryCallback(yapiHubDiscoveryCallback hubDiscoveryCallback)
Definition: yapi.c:4657
u16 yBlkHdl
Definition: ydef.h:213
RequestSt * ws
Definition: yproto.h:915
static void initializeAllCS(yContextSt *ctx)
Definition: yapi.c:1290
static void yapiSetTraceFile_internal(const char *file)
Definition: yapi.c:2808
char logicalname[YOCTO_LOGICAL_LEN]
Definition: ydef.h:455
int YAPI_FUNCTION_EXPORT yapiGetFunctionsByDevice(YAPI_DEVICE devdesc, YAPI_FUNCTION prevfundesc, YAPI_FUNCTION *buffer, int maxsize, int *neededsize, char *errmsg)
Definition: yapi.c:4552
YAPI_FUNCTION_EXPORT void yapiFreeMem(void *ptr)
Definition: yapi.c:4724
yRawNotificationCb rawNotificationCb
Definition: yproto.h:943
#define ySafeMemoryInit(nbentry)
Definition: ymemory.h:52
#define YOCTO_FUNCTION_LEN
Definition: ydef.h:425
void yInitWakeUpSocket(WakeUpSocket *wuce)
Definition: ytcp.c:218
static void yapiRegisterLogFunction_internal(yapiLogFunction logfun)
Definition: yapi.c:1497
yStrRef ypCateg
Definition: yapi.c:328
static void logResult(void *context, const u8 *result, u32 resultlen, int retcode, const char *errmsg)
Definition: yapi.c:396
static YRETCODE yapiPreregisterHub_internal(const char *url, char *errmsg)
Definition: yapi.c:2584
void YAPI_FUNCTION_EXPORT(* yapiFunctionUpdateCallback)(YAPI_FUNCTION fundescr, const char *value)
Definition: yapi.h:75
#define NOTIFY_NETPKT_FUNCV2YDX
Definition: ydef.h:683
int YAPI_FUNCTION_EXPORT yapiJsonGetPath(const char *path, const char *json_data, int json_size, const char **result, char *errmsg)
Definition: yapi.c:4691
yUrlRef hubref
Definition: yapi.c:323
yRawReportCb rawReportCb
Definition: yproto.h:944
static int yapiGetFunctionsByDevice_internal(YAPI_DEVICE devdesc, YAPI_FUNCTION prevfundesc, YAPI_FUNCTION *buffer, int maxsize, int *neededsize, char *errmsg)
Definition: yapi.c:3014
YAPI_DEVICE wpSearchByUrl(const char *host, const char *rootUrl)
Definition: yhash.c:1048
#define YASSERT(x)
Definition: yproto.h:454
SSDPInfos SSDP
Definition: yproto.h:949
int yReqHasPending(struct _HubSt *hub)
Definition: ytcp.c:1629
char firmware[YOCTO_FIRMWARE_LEN]
Definition: ydef.h:456
char * s_pwd
Definition: yproto.h:743
#define YSPRINTF
Definition: yproto.h:238
yJsonState st
Definition: yjson.h:84
u8 devYdxMap[ALLOC_YDX_PER_HUB]
Definition: yproto.h:818
YRETCODE YAPI_FUNCTION_EXPORT yapiHTTPRequestAsyncEx(const char *device, const char *request, int len, yapiRequestAsyncCallback callback, void *context, char *errmsg)
Definition: yapi.c:4620
YRETCODE YAPI_FUNCTION_EXPORT yapiHTTPRequestSyncDone(YIOHDL *iohdl, char *errmsg)
Definition: yapi.c:4611
YRETCODE YAPI_FUNCTION_EXPORT yapiHTTPRequestSyncStartOutOfBand(YIOHDL *iohdl, int channel, const char *device, const char *request, int requestsize, char **reply, int *replysize, yapiRequestProgressCallback progress_cb, void *progress_ctx, char *errmsg)
Definition: yapi.c:4601
int yapiJsonGetPath_internal(const char *path, const char *json_data, int json_size, int withHTTPheader, const char **output, char *errmsg)
Definition: yapi.c:3912
yHash yHashPutStr(const char *str)
Definition: yhash.c:318
void wpSafeRegister(HubSt *hub, u8 devYdx, yStrRef serialref, yStrRef lnameref, yStrRef productref, u16 deviceid, yUrlRef devUrl, s8 beacon)
Definition: yapi.c:599
void initDevYdxInfos(int devYdx, yStrRef serial)
Definition: yapi.c:379
#define ySafeMemoryDump(discard)
Definition: ymemory.h:53
YRETCODE YAPI_FUNCTION_EXPORT yapiGetAllJsonKeys(const char *json_buffer, char *buffer, int buffersize, int *fullsize, char *errmsg)
Definition: yapi.c:4706
#define YDLL_CALL_LEAVE(value)
Definition: yapi.c:4290
yapiDeviceLogCallback logDeviceCallback
Definition: yproto.h:952
u16 YAPI_FUNCTION_EXPORT yapiGetAPIVersion(const char **version, const char **apidate)
Definition: yapi.c:4472
int ypGetFunctionInfo(YAPI_FUNCTION fundesc, char *serial, char *funcId, char *baseType, char *funcName, char *funcVal)
Definition: yhash.c:1866
HubSt * hub
Definition: yapi.c:315
void(* yRawNotificationCb)(USB_Notify_Pkt *)
Definition: yapi.h:1054
YAPI_FUNCTION ypSearch(const char *class_str, const char *func_or_name)
Definition: yhash.c:1603
static YRETCODE yapiTestHub_internal(const char *url, int mstimeout, char *errmsg)
Definition: yapi.c:2508
static void yapiStartStopDeviceLogCallback_internal(const char *serial, int start)
Definition: yapi.c:1524
yBlkHdl yWpListHead
Definition: yhash.c:84
void yFifoEmpty(yFifoBuf *buf)
Definition: yfifo.c:100
#define NOTIFY_NETPKT_LOG
Definition: ydef.h:679
YRETCODE YAPI_FUNCTION_EXPORT yapiInitAPI(int detect_type, char *errmsg)
Definition: yapi.c:4295
YRETCODE YAPI_FUNCTION_EXPORT yapiGetFunctionInfoEx(YAPI_FUNCTION fundesc, YAPI_DEVICE *devdesc, char *serial, char *funcId, char *baseType, char *funcName, char *funcVal, char *errmsg)
Definition: yapi.c:4572
void YAPI_FUNCTION_EXPORT yapiRegisterDeviceChangeCallback(yapiDeviceUpdateCallback changeCallback)
Definition: yapi.c:4346
u16 yFifoGetFree(yFifoBuf *buf)
Definition: yfifo.c:401
void(* yRawReportV2Cb)(YAPI_DEVICE serialref, USB_Report_Pkt_V2 *report, int pktsize)
Definition: yapi.h:1056
char * s_user
Definition: yproto.h:741
int wpMarkForUnregister(yStrRef serial)
Definition: yhash.c:919
void yEnterCriticalSection(yCRITICAL_SECTION *cs)
Definition: ythread.c:647
#define yFree(ptr)
Definition: yproto.h:199
int yUsbTrafficPending(void)
Definition: ystream.c:2535
struct _YIOHDL_internal * next
Definition: yproto.h:907
static YRETCODE yapiLockFunctionCallBack_internal(char *errmsg)
Definition: yapi.c:2266
const int Y_DETECT_NET
Definition: yocto_api.h:205
static void skipJsonArray(yJsonStateMachine *j)
Definition: yapi.c:3747
ENU_PARSE_STATE state
Definition: yapi.c:316
char serial[YOCTO_SERIAL_LEN *2]
Definition: yproto.h:567
u16 deviceid
Definition: yproto.h:564
#define YSTRREF_MODULE_STRING
Definition: yhash.h:63
#define YIO_USB
Definition: ydef.h:243
int yUsbInit(yContextSt *ctx, char *errmsg)
Definition: ystream.c:2401
YRETCODE yapiPullDeviceLogEx(int devydx)
Definition: yapi.c:474
yAsbUrlProto
Definition: yhash.h:179
int s_next_async_id
Definition: yproto.h:781
static int pingURLOnhub(HubSt *hubst, const char *request, int mstimeout, char *errmsg)
Definition: yapi.c:2439
yapiDeviceUpdateCallback changeCallback
Definition: yproto.h:954
#define YAPI_FUNCTION_EXPORT
Definition: yapi.h:52
static void yapiFreeAPI_internal(void)
Definition: yapi.c:1440
void(* yapiRequestAsyncCallback)(void *context, const u8 *result, u32 resultlen, int retcode, const char *errmsg)
Definition: ydef.h:864
yBlkHdl yBlkListSeek(yBlkHdl hdl, u16 pos)
Definition: yhash.c:147
Definition: yhash.h:174
#define yMalloc(size)
Definition: yproto.h:198
double deviceTime
Definition: yproto.h:655
void YAPI_FUNCTION_EXPORT yapiStartStopDeviceLogCallback(const char *serial, int start)
Definition: yapi.c:4325
YRETCODE YAPI_FUNCTION_EXPORT yapiHTTPRequestAsync(const char *device, const char *request, yapiRequestAsyncCallback callback, void *context, char *errmsg)
Definition: yapi.c:4629
void YAPI_FUNCTION_EXPORT yapiSetTraceFile(const char *file)
Definition: yapi.c:4481
char errmsg[YOCTO_ERRMSG_LEN]
Definition: yproto.h:820
#define TRACEFILE_NAMELEN
Definition: yproto.h:987
#define YSTRLEN(str)
Definition: yproto.h:230
static void skipJsonStruct(yJsonStateMachine *j)
Definition: yapi.c:3732
yGenericDeviceSt generic_infos[ALLOC_YDX_PER_HUB]
Definition: yproto.h:929
#define NOTIFY_NETPKT_MAX_LEN
Definition: ydef.h:696
void(* yRawReportCb)(YAPI_DEVICE serialref, USB_Report_Pkt_V1 *report, int pktsize)
Definition: yapi.h:1055
int detecttype
Definition: yproto.h:932
void yDeleteCriticalSection(yCRITICAL_SECTION *cs)
Definition: ythread.c:682
u8 not_buffer[1024]
Definition: yproto.h:812
void MD5Initialize(HASH_SUM *ctx)
Definition: ykey.c:540
void yTcpShutdown(void)
Definition: ytcp.c:382
int yTryEnterCriticalSection(yCRITICAL_SECTION *cs)
Definition: ythread.c:657
u64 test_tout
Definition: yapi.c:2678
yStrRef serial
Definition: yapi.c:317
u8 beacon
Definition: ydef.h:457
int replybufsize
Definition: yproto.h:700
int yUsbWrite(YIOHDL_internal *ioghdl, const char *buffer, int writelen, char *errmsg)
Definition: ystream.c:2628
struct test_compile::@6 bytes
#define NETENUMLOG(fmt, args...)
Definition: yproto.h:371
int send_ping
Definition: yproto.h:802
static YRETCODE yapiUnlockDeviceCallBack_internal(char *errmsg)
Definition: yapi.c:2294
YRETCODE yapiCheckFirmware_internal(const char *serial, const char *rev, u32 flags, const char *path, char *buffer, int buffersize, int *fullsize, char *errmsg)
Definition: yprog.c:2333
yPrivDeviceSt * devs
Definition: yproto.h:934
yThread net_thread
Definition: yproto.h:807
yJsonState
Definition: yjson.h:52
#define NOTIFY_NETPKT_TIMEV2YDX
Definition: ydef.h:684
#define DEVGEN_LOG_PULLING
Definition: yproto.h:648
YUSBDEV devhdlcount
Definition: yproto.h:933
struct _RequestSt * notReq
Definition: yproto.h:737
static void yapiFreeHub(HubSt *hub)
Definition: yapi.c:1198
static YRETCODE yapiGetDevicePath_internal(YAPI_DEVICE devdesc, char *rootdevice, char *request, int requestsize, int *neededsize, char *errmsg)
Definition: yapi.c:2915
yCRITICAL_SECTION generic_cs
Definition: yproto.h:928
u16 devrelease
Definition: ydef.h:450
YAPI_DEVICE wpSearchEx(yStrRef strref)
Definition: yhash.c:988
void yFunctionUpdate(YAPI_FUNCTION fundescr, const char *value)
Definition: yapi.c:225
void YAPI_FUNCTION_EXPORT(* yapiDeviceLogCallback)(YAPI_FUNCTION fundescr, const char *line)
Definition: yapi.h:83
WakeUpSocket wuce
Definition: yproto.h:806
char * replybuf
Definition: yproto.h:699
void yReqClose(struct _RequestSt *req)
Definition: ytcp.c:1561
void wpSafeUpdate(HubSt *hub, u8 devYdx, yStrRef serialref, yStrRef lnameref, yUrlRef devUrl, s8 beacon)
Definition: yapi.c:659
#define INVALID_HASH_IDX
Definition: ydef.h:219
static int yapiJsonDecodeString_internal(const char *json_string, char *output)
Definition: yapi.c:3889
int yThreadIndex(void)
Definition: ythread.c:264
YRETCODE YAPI_FUNCTION_EXPORT yapiTriggerHubDiscovery(char *errmsg)
Definition: yapi.c:4664
static YRETCODE yapiUpdateDeviceList_internal(u32 forceupdate, char *errmsg)
Definition: yapi.c:2622
static int yapiGetSubdevices_internal(const char *serial, char *buffer, int buffersize, int *fullsize, char *errmsg)
Definition: yapi.c:3676
void YAPI_FUNCTION_EXPORT(* yapiLogFunction)(const char *log, u32 loglen)
Definition: yapi.h:65
struct _RequestSt * yReqAlloc(struct _HubSt *hub)
Definition: ytcp.c:1337
RequestSt * tcpreq[ALLOC_YDX_PER_HUB]
Definition: yproto.h:942
#define MAX_YDX_PER_HUB
Definition: yproto.h:727
char * s_nonce
Definition: yproto.h:744
u64 YAPI_FUNCTION_EXPORT yapiGetTickCount(void)
Definition: yapi.c:2713
YRETCODE YAPI_FUNCTION_EXPORT yapiSleep(int ms_duration, char *errmsg)
Definition: yapi.c:4455
YRETCODE YAPI_FUNCTION_EXPORT yapiHTTPRequestSyncStart(YIOHDL *iohdl, const char *device, const char *request, char **reply, int *replysize, char *errmsg)
Definition: yapi.c:4591
static int yapiGetFunctionsByClass_internal(const char *class_str, YAPI_FUNCTION prevfundesc, YAPI_FUNCTION *buffer, int maxsize, int *neededsize, char *errmsg)
Definition: yapi.c:2996
static YRETCODE yapiGetBootloaders_internal(char *buffer, int buffersize, int *fullsize, char *errmsg)
Definition: yapi.c:3586
#define YOCTO_API_BUILD_DATE
Definition: yversion.h:8
void YAPI_FUNCTION_EXPORT yapiRegisterFunctionUpdateCallback(yapiFunctionUpdateCallback updateCallback)
Definition: yapi.c:4353
int wpGetDeviceInfo(YAPI_DEVICE devdesc, u16 *deviceid, char *productname, char *serial, char *logicalname, u8 *beacon)
Definition: yhash.c:1220
static int yapiRequestOpenHTTP(YIOHDL_internal *iohdl, HubSt *hub, YAPI_DEVICE dev, const char *request, int reqlen, int wait_for_start, u64 mstimeout, yapiRequestAsyncCallback callback, void *context, char *errmsg)
Definition: yapi.c:3092
#define NOTIFY_NETPKT_NAME
Definition: ydef.h:672
yCRITICAL_SECTION enum_cs
Definition: yproto.h:931
static int yapiHTTPRequest_internal(const char *device, const char *request, char *buffer, int buffsize, int *fullsize, char *errmsg)
Definition: yapi.c:3496
yStrRef serial
Definition: yproto.h:650
#define YOCTO_HOSTNAME_NAME
Definition: yhash.h:171
u8 devYdx
Definition: yapi.c:325
#define DEVGEN_LOG_PENDING
Definition: yproto.h:647
void yThreadSignalEnd(yThread *yth)
Definition: ythread.c:326
char serial[YOCTO_SERIAL_LEN]
Definition: ydef.h:454
YRETCODE YAPI_FUNCTION_EXPORT yapiPreregisterHub(const char *url, char *errmsg)
Definition: yapi.c:4421
static void deleteAllCS(yContextSt *ctx)
Definition: yapi.c:1302
u16 nbinbterfaces
Definition: ydef.h:451
#define wpPreventUnregister()
Definition: yhash.h:243
int ymemfind(const u8 *haystack, u32 haystack_len, const u8 *needle, u32 needle_len)
Definition: ymemory.c:373
static void parseNetWpEntry(ENU_CONTEXT *enus)
Definition: yapi.c:717
void yapiRegisterRawReportCb(yRawReportCb callback)
Definition: yapi.c:4103
yUrlRef yHashUrlFromRef(yUrlRef urlref, const char *rootUrl)
Definition: yhash.c:454
YRETCODE YAPI_FUNCTION_EXPORT yapiUnlockDeviceCallBack(char *errmsg)
Definition: yapi.c:4394
u8 funYdx
Definition: yapi.c:332
int yTcpInit(char *errmsg)
Definition: ytcp.c:364
int errcode
Definition: yproto.h:819
void YAPI_FUNCTION_EXPORT yapiRegisterDeviceRemovalCallback(yapiDeviceUpdateCallback removalCallback)
Definition: yapi.c:4339
yUrlRef yHashUrl(const char *url, const char *rootUrl, u8 testonly, char *errmsg)
Definition: yhash.c:474
YRETCODE yapiHTTPRequestSyncStartEx_internal(YIOHDL *iohdl, int tcpchan, const char *device, const char *request, int requestsize, char **reply, int *replysize, yapiRequestProgressCallback progress_cb, void *progress_ctx, char *errmsg)
Definition: yapi.c:3348
void yCloseEvent(yEvent *ev)
Definition: ythread.c:223
yEvent exitSleepEvent
Definition: yproto.h:926
YRETCODE YAPI_FUNCTION_EXPORT yapiLockDeviceCallBack(char *errmsg)
Definition: yapi.c:4385
void YAPI_FUNCTION_EXPORT yapiUnregisterHub(const char *url)
Definition: yapi.c:4430
int ypRegister(yStrRef categ, yStrRef serial, yStrRef funcId, yStrRef funcName, int funClass, int funYdx, const char *funcVal)
Definition: yhash.c:1253
#define yMemcpy(dst, src, size)
Definition: yproto.h:204
YAPI_DEVICE wpSearch(const char *device_str)
Definition: yhash.c:1014
u64 test_pkt
Definition: yapi.c:2677
yStrRef * knownDevices
Definition: yapi.c:336
int yThreadMustEnd(yThread *yth)
Definition: ythread.c:338
#define NOTIFY_NETPKT_FUNCNAMEYDX
Definition: ydef.h:680
void yapiRegisterRawNotificationCb(yRawNotificationCb callback)
Definition: yapi.c:4093
YRETCODE YAPI_FUNCTION_EXPORT yapiUnlockFunctionCallBack(char *errmsg)
Definition: yapi.c:4376
YRETCODE YAPI_FUNCTION_EXPORT yapiGetSubdevices(const char *serial, char *buffer, int buffersize, int *fullsize, char *errmsg)
Definition: yapi.c:4758
#define YISERR(retcode)
Definition: ydef.h:394
static int yTcpTrafficPending(void)
Definition: yapi.c:2053
char productname[YOCTO_PRODUCTNAME_LEN]
Definition: ydef.h:453
s32 YAPI_DEVICE
Definition: ydef.h:216
ENU_PARSE_STATE
Definition: yapi.c:254
yJsonRetCode
Definition: yjson.h:99
yFifoBuf not_fifo
Definition: yproto.h:811
static YRETCODE yapiRegisterHub_internal(const char *url, char *errmsg)
Definition: yapi.c:2577
void YAPI_FUNCTION_EXPORT(* yapiHubDiscoveryCallback)(const char *serial, const char *url)
Definition: yapi.h:81
YRETCODE yUSBUpdateDeviceList(char *errmsg)
Definition: ystream.c:2191
static void wpUpdateTCP(HubSt *hub, const char *serial, const char *name, u8 beacon)
Definition: yapi.c:1635
#define YSTRNCMP(A, B, len)
Definition: yproto.h:227
int yThreadIsRunning(yThread *yth)
Definition: ythread.c:311
#define ALLOC_YDX_PER_HUB
Definition: yproto.h:728
YRETCODE yapiHTTPRequestSyncDone_internal(YIOHDL *iohdl, char *errmsg)
Definition: yapi.c:3398
static int yapiRequestOpenWS(YIOHDL_internal *iohdl, HubSt *hub, YAPI_DEVICE dev, int tcpchan, const char *request, int reqlen, u64 mstimeout, yapiRequestAsyncCallback callback, void *context, RequestProgress progress_cb, void *progress_ctx, char *errmsg)
Definition: yapi.c:3140
#define INVALID_YHANDLE
Definition: ydef.h:265
_FAR const char * state_end
Definition: yjson.h:94
void yThreadSignalStart(yThread *yth)
Definition: ythread.c:318
static YRETCODE yapiGetAllJsonKeys_internal(const char *json_buffer, char *buffer, int buffersize, int *fullsize, char *errmsg)
Definition: yapi.c:4032
Definition: yapi.c:257
YRETCODE yapiUpdateFirmware_internal(const char *serial, const char *firmwarePath, const char *settings, int force, int startUpdate, char *msg)
Definition: yprog.c:2362
yapiDeviceUpdateCallback removalCallback
Definition: yproto.h:955
yapiLogFunction log
Definition: yproto.h:951
#define YSTRCMP(A, B)
Definition: yproto.h:226
#define YOCTO_API_VERSION_STR
Definition: ydef.h:397
yapiHubDiscoveryCallback hubDiscoveryCallback
Definition: yproto.h:958
YRETCODE YAPI_FUNCTION_EXPORT yapiHTTPRequestAsyncOutOfBand(int channel, const char *device, const char *request, int requestsize, yapiRequestAsyncCallback callback, void *context, char *errmsg)
Definition: yapi.c:4638
#define YIO_TCP
Definition: ydef.h:244
void ypUpdateYdx(int devydx, Notification_funydx funInfo, const char *funcval)
Definition: ystream.c:286
#define NB_MAX_DEVICES
Definition: yhash.h:59
s32 YUSBDEV
Definition: ydef.h:239
#define YOCTO_AKA_YFUNCTION
Definition: ydef.h:413
#define YIO_WS
Definition: ydef.h:247
void YAPI_FUNCTION_EXPORT yapiRegisterDeviceArrivalCallback(yapiDeviceUpdateCallback arrivalCallback)
Definition: yapi.c:4332
#define YSTRNCPY(dst, dstsize, src, len)
Definition: yproto.h:237
u16 ySeekFifo(yFifoBuf *buf, const u8 *pattern, u16 patlen, u16 startofs, u16 searchlen, u8 bTextCompare)
Definition: yfifo.c:367
struct _yPrivDeviceSt * next
Definition: yproto.h:704
YRETCODE YAPI_FUNCTION_EXPORT yapiGetDeviceInfo(YAPI_DEVICE devdesc, yDeviceSt *infos, char *errmsg)
Definition: yapi.c:4506
u16 yPopFifo(yFifoBuf *buf, u8 *data, u16 datalen)
Definition: yfifo.c:187
#define YIO_DEFAULT_TCP_TIMEOUT
Definition: ydef.h:250
char value[256]
Definition: yapi.c:3946
int yReqIsEof(struct _RequestSt *req, char *errmsg)
Definition: ytcp.c:1486
u32 raw
Definition: yapi.c:1320
YRETCODE YAPI_FUNCTION_EXPORT yapiUpdateDeviceList(u32 forceupdate, char *errmsg)
Definition: yapi.c:4437
static void asyncDrop(void *context, const u8 *result, u32 resultlen, int retcode, const char *errmsg)
Definition: yapi.c:3446
int YFOPEN(FILE **f, const char *filename, const char *mode)
Definition: ystream.c:130
YAPI_FUNCTION_EXPORT void * yapiGetMem(int size)
Definition: yapi.c:4715
#define NOTIFY_NETPKT_FUNCVALYDX
Definition: ydef.h:687
YRETCODE YAPI_FUNCTION_EXPORT yapiCheckFirmware(const char *serial, const char *rev, const char *path, char *buffer, int buffersize, int *fullsize, char *errmsg)
Definition: yapi.c:4730
YUSBDEV findDevHdlFromStr(const char *str)
Definition: ystream.c:2299
static YRETCODE yapiSleep_internal(int ms_duration, char *errmsg)
Definition: yapi.c:2680
void MD5AddData(HASH_SUM *ctx, const u8 *buf, u32 len)
Definition: ykey.c:634
int wpRegister(int devYdx, yStrRef serial, yStrRef logicalName, yStrRef productName, u16 productId, yUrlRef devUrl, s8 beacon)
Definition: yhash.c:783
static YRETCODE yapiRegisterHubEx(const char *url, int checkacces, char *errmsg)
Definition: yapi.c:2303
#define YOCTO_API_BUILD_NO
Definition: yversion.h:2
static int yapiRequestWaitEndHTTP(YIOHDL_internal *iohdl, char **reply, int *replysize, char *errmsg)
Definition: yapi.c:3297
int YAPI_FUNCTION_EXPORT yapiHTTPRequest(const char *device, const char *request, char *buffer, int buffsize, int *fullsize, char *errmsg)
Definition: yapi.c:4648
HTTPNetHub http
Definition: yproto.h:823
yUrlRef wpGetDeviceUrlRef(YAPI_DEVICE devdesc)
Definition: yhash.c:1102
YRETCODE YAPI_FUNCTION_EXPORT yapiRegisterHub(const char *url, char *errmsg)
Definition: yapi.c:4412
YRETCODE YAPI_FUNCTION_EXPORT yapiHandleEvents(char *errmsg)
Definition: yapi.c:4446
YRETCODE YAPI_FUNCTION_EXPORT yapiUpdateFirmwareEx(const char *serial, const char *firmwarePath, const char *settings, int force, int startUpdate, char *msg)
Definition: yapi.c:4748
YRETCODE YAPI_FUNCTION_EXPORT yapiGetDevicePathEx(const char *serial, char *rootdevice, char *request, int requestsize, int *neededsize, char *errmsg)
Definition: yapi.c:4524


yoctopuce_altimeter
Author(s): Anja Sheppard
autogenerated on Mon Jun 10 2019 15:49:10