예제 #1
0
OSStatus MICOStartBonjourService( WiFi_Interface interface, mico_Context_t * const inContext )
{
  char *temp_txt= NULL;
  char *temp_txt2;
  OSStatus err;
  net_para_st para;
  bonjour_init_t init;

  temp_txt = malloc(500);
  require_action(temp_txt, exit, err = kNoMemoryErr);

  memset(&init, 0x0, sizeof(bonjour_init_t));

  micoWlanGetIPStatus(&para, Station);

  init.service_name = BONJOUR_SERVICE;

  /*   name#xxxxxx.local.  */
  snprintf( temp_txt, 100, "%s#%c%c%c%c%c%c.local.", inContext->flashContentInRam.micoSystemConfig.name, 
                                                     inContext->micoStatus.mac[9],  inContext->micoStatus.mac[10], \
                                                     inContext->micoStatus.mac[12], inContext->micoStatus.mac[13], \
                                                     inContext->micoStatus.mac[15], inContext->micoStatus.mac[16] );
  init.host_name = (char*)__strdup(temp_txt);

  /*   name#xxxxxx.   */
  snprintf( temp_txt, 100, "%s#%c%c%c%c%c%c",        inContext->flashContentInRam.micoSystemConfig.name, 
                                                     inContext->micoStatus.mac[9],  inContext->micoStatus.mac[10], \
                                                     inContext->micoStatus.mac[12], inContext->micoStatus.mac[13], \
                                                     inContext->micoStatus.mac[15], inContext->micoStatus.mac[16] );
  init.instance_name = (char*)__strdup(temp_txt);

  init.service_port = inContext->flashContentInRam.appConfig.bonjourServicePort;
  init.interface = interface;

  temp_txt2 = __strdup_trans_dot(inContext->micoStatus.mac);
  sprintf(temp_txt, "MAC=%s.", temp_txt2);
  free(temp_txt2);

  temp_txt2 = __strdup_trans_dot(FIRMWARE_REVISION);
  sprintf(temp_txt, "%sFirmware Rev=%s.", temp_txt, temp_txt2);
  free(temp_txt2);
  
  temp_txt2 = __strdup_trans_dot(HARDWARE_REVISION);
  sprintf(temp_txt, "%sHardware Rev=%s.", temp_txt, temp_txt2);
  free(temp_txt2);

  temp_txt2 = __strdup_trans_dot(MicoGetVer());
  sprintf(temp_txt, "%sMICO OS Rev=%s.", temp_txt, temp_txt2);
  free(temp_txt2);

  temp_txt2 = __strdup_trans_dot(MODEL);
  sprintf(temp_txt, "%sModel=%s.", temp_txt, temp_txt2);
  free(temp_txt2);

  temp_txt2 = __strdup_trans_dot(PROTOCOL);
  sprintf(temp_txt, "%sProtocol=%s.", temp_txt, temp_txt2);
  free(temp_txt2);

  temp_txt2 = __strdup_trans_dot(MANUFACTURER);
  sprintf(temp_txt, "%sManufacturer=%s.", temp_txt, temp_txt2);
  free(temp_txt2);
  
  sprintf(temp_txt, "%sSeed=%u.", temp_txt, inContext->flashContentInRam.micoSystemConfig.seed);
  init.txt_record = (char*)__strdup(temp_txt);

  bonjour_service_init(init);

  free(init.host_name);
  free(init.instance_name);
  free(init.txt_record);

  err = MICOAddNotification( mico_notify_WIFI_STATUS_CHANGED, (void *)BonjourNotify_WifiStatusHandler );
  require_noerr( err, exit );
  err = MICOAddNotification( mico_notify_SYS_WILL_POWER_OFF, (void *)BonjourNotify_SYSWillPoerOffHandler );
  require_noerr( err, exit ); 

  start_bonjour_service();
  _bonjourStarted = true;

exit:
  if(temp_txt) free(temp_txt);
  return err;
}
예제 #2
0
void init_platform_bootloader( void )
{
  CRC8_Context crc;
  OSStatus err = kNoErr;
  mico_logic_partition_t *rf_partition = MicoFlashGetInfo( MICO_PARTITION_RF_FIRMWARE );
  
  MicoGpioInitialize( (mico_gpio_t)MICO_SYS_LED, OUTPUT_PUSH_PULL );
  MicoGpioOutputLow( (mico_gpio_t)MICO_SYS_LED );
  MicoGpioInitialize( (mico_gpio_t)MICO_RF_LED, OUTPUT_OPEN_DRAIN_NO_PULL );
  MicoGpioOutputHigh( (mico_gpio_t)MICO_RF_LED );
  
  MicoGpioInitialize((mico_gpio_t)BOOT_SEL, INPUT_PULL_UP);
  MicoGpioInitialize((mico_gpio_t)MFG_SEL, INPUT_PULL_UP);
  
#ifdef USE_MiCOKit_EXT
  dc_motor_init( );
  dc_motor_set( 0 );
  
  rgb_led_init();
  rgb_led_open(0, 0, 0);
#endif
  
  /* Specific operations used in EMW3165 production */
#define NEED_RF_DRIVER_COPY_BASE    ((uint32_t)0x08008000)
#define TEMP_RF_DRIVER_BASE         ((uint32_t)0x08040000)
#define TEMP_RF_DRIVER_END          ((uint32_t)0x0807FFFF)
  
  const uint8_t isDriverNeedCopy = *(uint8_t *)(NEED_RF_DRIVER_COPY_BASE);
  const uint32_t totalLength = rf_partition->partition_length;
  const uint8_t crcResult = *(uint8_t *)(TEMP_RF_DRIVER_END);
  uint8_t targetCrcResult = 0;
  
  uint32_t copyLength;
  uint32_t destStartAddress_tmp = rf_partition->partition_start_addr;
  uint32_t sourceStartAddress_tmp = TEMP_RF_DRIVER_BASE;
  uint32_t i;
  
  if ( isDriverNeedCopy != 0x0 )
    return;
  
  platform_log( "Bootloader start to copy RF driver..." );
  /* Copy RF driver to SPI flash */

  err = platform_flash_init( &platform_flash_peripherals[ MICO_FLASH_SPI ] );
  require_noerr(err, exit);
  err = platform_flash_init( &platform_flash_peripherals[ MICO_FLASH_EMBEDDED ] );
  require_noerr(err, exit);
  err = platform_flash_erase( &platform_flash_peripherals[ MICO_FLASH_SPI ], 
    rf_partition->partition_start_addr, rf_partition->partition_start_addr + rf_partition->partition_length - 1 );
  require_noerr(err, exit);
  platform_log( "Time: %d", mico_get_time_no_os() );
  
  for(i = 0; i <= totalLength/SizePerRW; i++){
    if( i == totalLength/SizePerRW ){
      if(totalLength%SizePerRW)
        copyLength = totalLength%SizePerRW;
      else
        break;
    }else{
      copyLength = SizePerRW;
    }
    printf(".");
    err = platform_flash_read( &platform_flash_peripherals[ MICO_FLASH_EMBEDDED ], &sourceStartAddress_tmp, data , copyLength );
    require_noerr( err, exit );
    err = platform_flash_write( &platform_flash_peripherals[ MICO_FLASH_SPI ], &destStartAddress_tmp, data, copyLength );
    require_noerr(err, exit);
  }
  
  printf("\r\n");
  /* Check CRC-8 check-sum */
  platform_log( "Bootloader start to verify RF driver..." );
  sourceStartAddress_tmp = TEMP_RF_DRIVER_BASE;
  destStartAddress_tmp = rf_partition->partition_start_addr;
  
  CRC8_Init( &crc );
  for(i = 0; i <= totalLength/SizePerRW; i++){
    if( i == totalLength/SizePerRW ){
      if(totalLength%SizePerRW)
        copyLength = totalLength%SizePerRW;
      else
        break;
    }else{
      copyLength = SizePerRW;
    }
    printf(".");
    err = platform_flash_read( &platform_flash_peripherals[ MICO_FLASH_SPI ], &destStartAddress_tmp, data, copyLength );
    require_noerr( err, exit );   
      
    CRC8_Update( &crc, data, copyLength);
  }
  CRC8_Final( &crc, &targetCrcResult );
  
  printf("\r\n");
  //require_string( crcResult == targetCrcResult, exit, "Check-sum error" ); 
  if( crcResult != targetCrcResult ){
    platform_log("Check-sum error");
    while(1);
  }
  /* Clear RF driver from temperary storage */
  platform_log("Bootloader start to clear RF driver temporary storage...");
  
  /* Clear copy tag */
  err = platform_flash_erase( &platform_flash_peripherals[ MICO_FLASH_EMBEDDED ], NEED_RF_DRIVER_COPY_BASE, NEED_RF_DRIVER_COPY_BASE);
  require_noerr(err, exit);
  
exit:
  return;
}
예제 #3
0
static OSStatus validateTSAResponseAndAddTimeStamp(SecCmsSignerInfoRef signerinfo, CSSM_DATA_PTR tsaResponse,
    uint64_t expectedNonce)
{
    OSStatus status = SECFailure;
    SecAsn1CoderRef coder = NULL;
    SecAsn1TimeStampRespDER respDER = {{{0}},};
    SecAsn1TSAPKIStatusInfo *tsastatus = NULL;
    int respstatus = -1;
    int failinfo = -1;

    require_action(tsaResponse && tsaResponse->Data && tsaResponse->Length, xit, status = errSecTimestampMissing);

    require_noerr(SecAsn1CoderCreate(&coder), xit);
    require_noerr(SecTSAResponseCopyDEREncoding(coder, tsaResponse, &respDER), xit);

#ifndef NDEBUG
    tsaWriteFileX("/tmp/tsa-timeStampToken.der", respDER.timeStampTokenDER.Data, respDER.timeStampTokenDER.Length);
#endif

    tsastatus = (SecAsn1TSAPKIStatusInfo *)&respDER.status;
    require_action(tsastatus->status.Data, xit, status = errSecTimestampBadDataFormat);
    respstatus = (int)tsaDER_ToInt(&tsastatus->status);

#ifndef NDEBUG
    char buf[80]={0,};
    if (tsastatus->failInfo.Data)   // e.g. FI_BadRequest
        failinfo = (int)tsaDER_ToInt(&tsastatus->failInfo);
    
    if (tsastatus->statusString.Data && tsastatus->statusString.Length)
    {
        OSStatus strrx = decodeDERUTF8String(&tsastatus->statusString, buf, sizeof(buf));
        dprintf("decodeDERUTF8String status: %d\n", (int)strrx);
    }

    dprintf("validateTSAResponse: status: %d, failinfo: %d, %s\n", respstatus, failinfo, buf);
#endif

    switch (respstatus)
    {
    case PKIS_Granted:
    case PKIS_GrantedWithMods:  // Success
        status = noErr;
        break;
    case PKIS_Rejection:
        status = errSecTimestampRejection;
        break;
    case PKIS_Waiting:
        status = errSecTimestampWaiting;
        break;
    case PKIS_RevocationWarning:
        status = errSecTimestampRevocationWarning;
        break;
    case PKIS_RevocationNotification:
        status = errSecTimestampRevocationNotification;
        break;
    default:
        status = errSecTimestampSystemFailure;
        break;
    }
    require_noerr(status, xit);
    
    // If we succeeded, then we must have a TimeStampToken
    
    require_action(respDER.timeStampTokenDER.Data && respDER.timeStampTokenDER.Length, xit, status = errSecTimestampBadDataFormat);

    dprintf("timestamp full expected nonce: %lld\n", expectedNonce);
    
    /*
        The bytes in respDER are a full CMS message, which we need to check now for validity.
        The code for this is essentially the same code taht is done during a timestamp
        verify, except that we also need to check the nonce.
    */
    require_noerr(status = decodeTimeStampToken(signerinfo, &respDER.timeStampTokenDER, NULL, expectedNonce), xit);

    status = SecCmsSignerInfoAddTimeStamp(signerinfo, &respDER.timeStampTokenDER);

xit:
    if (coder)
        SecAsn1CoderRelease(coder);
    return status;
}
예제 #4
0
파일: kxld_vtable.c 프로젝트: Algozjb/xnu
/*******************************************************************************
* Patching vtables allows us to preserve binary compatibility across releases.
*******************************************************************************/
kern_return_t
kxld_vtable_patch(KXLDVTable *vtable, const KXLDVTable *super_vtable,
    KXLDObject *object)
{
    kern_return_t rval = KERN_FAILURE;
    const KXLDSymtab *symtab = NULL;
    const KXLDSym *sym = NULL;
    KXLDVTableEntry *child_entry = NULL;
    KXLDVTableEntry *parent_entry = NULL;
    u_int symindex = 0;
    u_int i = 0;
    char *demangled_name1 = NULL;
    char *demangled_name2 = NULL;
    char *demangled_name3 = NULL;
    size_t demangled_length1 = 0;
    size_t demangled_length2 = 0;
    size_t demangled_length3 = 0;
    boolean_t failure = FALSE;

    check(vtable);
    check(super_vtable);

    symtab = kxld_object_get_symtab(object);

    require_action(!vtable->is_patched, finish, rval=KERN_SUCCESS);
    require_action(super_vtable->is_patched, finish, rval=KERN_FAILURE);
    require_action(vtable->entries.nitems >= super_vtable->entries.nitems, finish,
        rval=KERN_FAILURE;
        kxld_log(kKxldLogPatching, kKxldLogErr, kKxldLogMalformedVTable, 
            kxld_demangle(vtable->name, &demangled_name1, &demangled_length1)));

    for (i = 0; i < super_vtable->entries.nitems; ++i) {
        child_entry = kxld_array_get_item(&vtable->entries, i);
        parent_entry = kxld_array_get_item(&super_vtable->entries, i);

        /* The child entry can be NULL when a locally-defined, non-external
         * symbol is stripped.  We wouldn't patch this entry anyway, so we
         * just skip it.
         */

        if (!child_entry->unpatched.sym) continue;

        /* It's possible for the patched parent entry not to have a symbol
         * (e.g. when the definition is inlined).  We can't patch this entry no
         * matter what, so we'll just skip it and die later if it's a problem
         * (which is not likely).
         */

        if (!parent_entry->patched.name) continue;
        
        /* 1) If the symbol is defined locally, do not patch */

        if (kxld_sym_is_defined_locally(child_entry->unpatched.sym)) continue;

        /* 2) If the child is a pure virtual function, do not patch.
         * In general, we want to proceed with patching when the symbol is 
         * externally defined because pad slots fall into this category.
         * The pure virtual function symbol is special case, as the pure
         * virtual property itself overrides the parent's implementation.
         */

        if (kxld_sym_is_pure_virtual(child_entry->unpatched.sym)) continue;

        /* 3) If the symbols are the same, do not patch */

        if (streq(child_entry->unpatched.sym->name, 
                  parent_entry->patched.name)) 
        {
            continue;
        }

        /* 4) If the parent vtable entry is a pad slot, and the child does not
         * match it, then the child was built against a newer version of the
         * libraries, so it is binary-incompatible.
         */

        require_action(!kxld_sym_name_is_padslot(parent_entry->patched.name),
            finish, rval=KERN_FAILURE;
            kxld_log(kKxldLogPatching, kKxldLogErr, 
                kKxldLogParentOutOfDate, 
                kxld_demangle(super_vtable->name, &demangled_name1, 
                    &demangled_length1), 
                kxld_demangle(vtable->name, &demangled_name2, 
                    &demangled_length2)));

#if KXLD_USER_OR_STRICT_PATCHING
        /* 5) If we are doing strict patching, we prevent kexts from declaring
         * virtual functions and not implementing them.  We can tell if a
         * virtual function is declared but not implemented because we resolve
         * symbols before patching; an unimplemented function will still be
         * undefined at this point.  We then look at whether the symbol has
         * the same class prefix as the vtable.  If it does, the symbol was
         * declared as part of the class and not inherited, which means we
         * should not patch it.
         */

        if (kxld_object_target_supports_strict_patching(object) && 
            !kxld_sym_is_defined(child_entry->unpatched.sym))
        {
            char class_name[KXLD_MAX_NAME_LEN];
            char function_prefix[KXLD_MAX_NAME_LEN];
            u_long function_prefix_len = 0;

            rval = kxld_sym_get_class_name_from_vtable_name(vtable->name,
                class_name, sizeof(class_name));
            require_noerr(rval, finish);

            function_prefix_len = 
                kxld_sym_get_function_prefix_from_class_name(class_name,
                    function_prefix, sizeof(function_prefix));
            require(function_prefix_len, finish);

            if (!strncmp(child_entry->unpatched.sym->name, 
                    function_prefix, function_prefix_len)) 
            {
                failure = TRUE;
                kxld_log(kKxldLogPatching, kKxldLogErr,
                    "The %s is unpatchable because its class declares the "
                    "method '%s' without providing an implementation.",
                    kxld_demangle(vtable->name,
                        &demangled_name1, &demangled_length1),
                    kxld_demangle(child_entry->unpatched.sym->name,
                        &demangled_name2, &demangled_length2));
                continue;
            }
        }
#endif /* KXLD_USER_OR_STRICT_PATCHING */
    
        /* 6) The child symbol is unresolved and different from its parent, so
         * we need to patch it up.  We do this by modifying the relocation
         * entry of the vtable entry to point to the symbol of the parent
         * vtable entry.  If that symbol does not exist (i.e. we got the data
         * from a link state object's vtable representation), then we create a
         * new symbol in the symbol table and point the relocation entry to
         * that.
         */

        sym = kxld_symtab_get_locally_defined_symbol_by_name(symtab, 
            parent_entry->patched.name);
        if (!sym) {
            rval = kxld_object_add_symbol(object, parent_entry->patched.name,
                parent_entry->patched.addr, &sym);
            require_noerr(rval, finish);
        }
        require_action(sym, finish, rval=KERN_FAILURE);

        rval = kxld_symtab_get_sym_index(symtab, sym, &symindex);
        require_noerr(rval, finish);

        rval = kxld_reloc_update_symindex(child_entry->unpatched.reloc, symindex);
        require_noerr(rval, finish);
        kxld_log(kKxldLogPatching, kKxldLogDetail,
            "In vtable '%s', patching '%s' with '%s'.", 
            kxld_demangle(vtable->name, &demangled_name1, &demangled_length1),
            kxld_demangle(child_entry->unpatched.sym->name, 
                &demangled_name2, &demangled_length2), 
            kxld_demangle(sym->name, &demangled_name3, &demangled_length3));

        rval = kxld_object_patch_symbol(object, child_entry->unpatched.sym);
        require_noerr(rval, finish);

        child_entry->unpatched.sym = sym;

        /*
         * The C++ ABI requires that functions be aligned on a 2-byte boundary:
         * http://www.codesourcery.com/public/cxx-abi/abi.html#member-pointers
         * If the LSB of any virtual function's link address is 1, then the
         * compiler has violated that part of the ABI, and we're going to panic
         * in _ptmf2ptf() (in OSMetaClass.h). Better to panic here with some
         * context.
         */
        assert(kxld_sym_is_pure_virtual(sym) || !(sym->link_addr & 1)); 
    }

    require_action(!failure, finish, rval=KERN_FAILURE);

    /* Change the vtable representation from the unpatched layout to the
     * patched layout.
     */

    for (i = 0; i < vtable->entries.nitems; ++i) {
        char *name;
        kxld_addr_t addr;

        child_entry = kxld_array_get_item(&vtable->entries, i);
        if (child_entry->unpatched.sym) {
            name = child_entry->unpatched.sym->name;
            addr = child_entry->unpatched.sym->link_addr;
        } else {
            name = NULL;
            addr = 0;
        }

        child_entry->patched.name = name;
        child_entry->patched.addr = addr;
    }

    vtable->is_patched = TRUE;
    rval = KERN_SUCCESS;

finish:
    if (demangled_name1) kxld_free(demangled_name1, demangled_length1);
    if (demangled_name2) kxld_free(demangled_name2, demangled_length2);
    if (demangled_name3) kxld_free(demangled_name3, demangled_length3);
    
    return rval;
}
예제 #5
0
OSStatus HTTPHeaderParse( HTTPHeader_t *ioHeader )
{
    OSStatus            err;
    const char *        src;
    const char *        end;
    const char *        ptr;
    char                c;
    const char *        value;
    size_t              valueSize;
    int                 x;

    require_action( ioHeader->len < sizeof( ioHeader->buf ), exit, err = kParamErr );

    // Reset fields up-front to good defaults to simplify handling of unused fields later.

    ioHeader->methodPtr         = "";
    ioHeader->methodLen         = 0;
    ioHeader->urlPtr            = "";
    ioHeader->urlLen            = 0;
    memset( &ioHeader->url, 0, sizeof( ioHeader->url ) );
    ioHeader->protocolPtr       = "";
    ioHeader->protocolLen       = 0;
    ioHeader->statusCode        = -1;
    ioHeader->reasonPhrasePtr   = "";
    ioHeader->reasonPhraseLen   = 0;
    ioHeader->channelID         = 0;
    ioHeader->contentLength     = 0;
    ioHeader->persistent        = false;

    // Check for a 4-byte interleaved binary data header (see RFC 2326 section 10.12). It has the following format:
    //
    //      '$' <1:channelID> <2:dataSize in network byte order> ... followed by dataSize bytes of binary data.
    src = ioHeader->buf;
    if( ( ioHeader->len == 4 ) && ( src[ 0 ] == '$' ) )
    {
        const uint8_t *     usrc;

        usrc = (const uint8_t *) src;
        ioHeader->channelID     =   usrc[ 1 ];
        ioHeader->contentLength = ( usrc[ 2 ] << 8 ) | usrc[ 3 ];

        ioHeader->methodPtr = src;
        ioHeader->methodLen = 1;

        err = kNoErr;
        goto exit;
    }

    // Parse the start line. This will also determine if it's a request or response.
    // Requests are in the format <method> <url> <protocol>/<majorVersion>.<minorVersion>, for example:
    //
    //      GET /abc/xyz.html HTTP/1.1
    //      GET http://www.host.com/abc/xyz.html HTTP/1.1
    //      GET http://user:[email protected]/abc/xyz.html HTTP/1.1
    //
    // Responses are in the format <protocol>/<majorVersion>.<minorVersion> <statusCode> <reasonPhrase>, for example:
    //
    //      HTTP/1.1 404 Not Found
    ptr = src;
    end = src + ioHeader->len;
    for( c = 0; ( ptr < end ) && ( ( c = *ptr ) != ' ' ) && ( c != '/' ); ++ptr ) {}
    require_action( ptr < end, exit, err = kMalformedErr );

    if( c == ' ' ) // Requests have a space after the method. Responses have '/' after the protocol.
    {
        ioHeader->methodPtr = src;
        ioHeader->methodLen = (size_t)( ptr - src );
        ++ptr;

        // Parse the URL.
        ioHeader->urlPtr = ptr;
        while( ( ptr < end ) && ( *ptr != ' ' ) ) ++ptr;
        ioHeader->urlLen = (size_t)( ptr - ioHeader->urlPtr );
        require_action( ptr < end, exit, err = kMalformedErr );
        ++ptr;

        err = URLParseComponents( ioHeader->urlPtr, ioHeader->urlPtr + ioHeader->urlLen, &ioHeader->url, NULL );
        require_noerr( err, exit );

        // Parse the protocol and version.
        ioHeader->protocolPtr = ptr;
        while( ( ptr < end ) && ( ( c = *ptr ) != '\r' ) && ( c != '\n' ) ) ++ptr;
        ioHeader->protocolLen = (size_t)( ptr - ioHeader->protocolPtr );
        require_action( ptr < end, exit, err = kMalformedErr );
        ++ptr;
    }
    else // Response
    {
        // Parse the protocol version.
        ioHeader->protocolPtr = src;
        for( ++ptr; ( ptr < end ) && ( *ptr != ' ' ); ++ptr ) {}
        ioHeader->protocolLen = (size_t)( ptr - ioHeader->protocolPtr );
        require_action( ptr < end, exit, err = kMalformedErr );
        ++ptr;

        // Parse the status code.
        x = 0;
        for( c = 0; ( ptr < end ) && ( ( c = *ptr ) >= '0' ) && ( c <= '9' ); ++ptr ) x = ( x * 10 ) + ( c - '0' );
        ioHeader->statusCode = x;
        if( c == ' ' ) ++ptr;

        // Parse the reason phrase.
        ioHeader->reasonPhrasePtr = ptr;
        while( ( ptr < end ) && ( ( c = *ptr ) != '\r' ) && ( c != '\n' ) ) ++ptr;
        ioHeader->reasonPhraseLen = (size_t)( ptr - ioHeader->reasonPhrasePtr );
        require_action( ptr < end, exit, err = kMalformedErr );
        ++ptr;
    }

    // There should at least be a blank line after the start line so make sure there's more data.
    require_action( ptr < end, exit, err = kMalformedErr );

    // Determine persistence. Note: HTTP 1.0 defaults to non-persistent if a Connection header field is not present.
    err = HTTPGetHeaderField( ioHeader->buf, ioHeader->len, "Connection", NULL, NULL, &value, &valueSize, NULL );
    if( err )   ioHeader->persistent = (Boolean)( strnicmpx( ioHeader->protocolPtr, ioHeader->protocolLen, "HTTP/1.0" ) != 0 );
    else        ioHeader->persistent = (Boolean)( strnicmpx( value, valueSize, "close" ) != 0 );

    err = HTTPGetHeaderField( ioHeader->buf, ioHeader->len, "Transfer-Encoding", NULL, NULL, &value, &valueSize, NULL );
    if( err )   ioHeader->chunkedData = false;
    else        ioHeader->chunkedData = (Boolean)( strnicmpx( value, valueSize, kTransferrEncodingType_CHUNKED ) == 0 );

    // Content-Length is such a common field that we get it here during general parsing.
    HTTPScanFHeaderValue( ioHeader->buf, ioHeader->len, "Content-Length", "%llu", &ioHeader->contentLength );

    err = kNoErr;

exit:
    return err;
}
예제 #6
0
파일: OpaqueIDs.c 프로젝트: aosm/webdavfs
int AssignOpaqueID(void *inData, opaque_id *outID)
{
	int error;
	u_int32_t entryToUse;
	
	require_action(outID != NULL, bad_parameter, error = EINVAL);
	
	*outID = kInvalidOpaqueID;
	
	error = pthread_mutex_lock(&gOpaqueEntryMutex);
	require_noerr(error, pthread_mutex_lock);
	
	/*
	 * If there aren't any items in the table, or if the number of free items is
	 * lower than we want, then grow the table.
	 */
	if ( (gIndexOfFreeOpaqueEntryHead == 0) || ((gOpaqueEntriesAllocated - gOpaqueEntriesUsed) < kOpaqueIDMinimumFree) )
	{
		u_int32_t newCount;
		
		newCount = MIN(gOpaqueEntriesAllocated + 2048, kOpaqueIDMaximumCount);

		if ( gOpaqueEntriesAllocated < newCount )
		{
			OpaqueEntryArrayPtr nuids;
			
			nuids = (OpaqueEntryArrayPtr)realloc(gOpaqueEntryArray, sizeof(struct OpaqueEntry) * newCount);

			if ( nuids != NULL )
			{
				u_int32_t i;

				gOpaqueEntryArray = nuids;

				/* Add all the 'new' OpaqueEntry to the free list. */
				for ( i = 0; i < newCount - gOpaqueEntriesAllocated; ++i )
				{
					/* set both count and index to 0 */
					gOpaqueEntryArray[gOpaqueEntriesAllocated + i].id = 0;

					AddToFreeList(gOpaqueEntriesAllocated + i);
				}

				gOpaqueEntriesAllocated = newCount;
			}
		}
	}

	/* get index of an OpaqueEntry to use */
	entryToUse = RemoveFromFreeList();

	/* release the lock */
	pthread_mutex_unlock(&gOpaqueEntryMutex);

	/* did we get an OpaqueEntry? */
	require_action((entryToUse != 0) && (entryToUse < gOpaqueEntriesAllocated), no_opaqueID, error = EINVAL);
		
	/* the new id is created with the previous counter + 1, and the index */
	gOpaqueEntryArray[entryToUse].id = CreateOpaqueID(GetOpaqueIDCounterPart(gOpaqueEntryArray[entryToUse].id) + 1, entryToUse);
	gOpaqueEntryArray[entryToUse].data = inData;
	
	*outID = gOpaqueEntryArray[entryToUse].id;

	++gOpaqueEntriesUsed;

no_opaqueID:
pthread_mutex_lock:
bad_parameter:

	return ( error );
}
예제 #7
0
파일: kxld_vtable.c 프로젝트: Algozjb/xnu
/*******************************************************************************
* Initializes a vtable object by reading the symbol values out of the vtable
* entries and performing reverse symbol lookups on those values.
*******************************************************************************/
static kern_return_t
init_by_entries(KXLDVTable *vtable, const KXLDRelocator *relocator,
    const KXLDDict *defined_cxx_symbols)
{
    kern_return_t rval = KERN_FAILURE;
    KXLDVTableEntry *tmpentry = NULL;
    KXLDSym *sym = NULL;
    kxld_addr_t entry_value = 0;
    u_long entry_offset;
    u_int vtable_entry_size = 0;
    u_int vtable_header_size = 0;
    u_int nentries = 0;
    u_int i = 0;

    check(vtable);
    check(relocator);

    (void) get_vtable_base_sizes(relocator->is_32_bit, 
        &vtable_entry_size, &vtable_header_size);

    /* Count the number of entries (the vtable is null-terminated) */

    entry_offset = vtable_header_size;
    while (1) {
        entry_value = kxld_relocator_get_pointer_at_addr(relocator,
            vtable->vtable, entry_offset);
        if (!entry_value) break;

        entry_offset += vtable_entry_size;
        ++nentries;
    }

    /* Allocate the symbol index */

    rval = kxld_array_init(&vtable->entries, sizeof(KXLDVTableEntry), nentries);
    require_noerr(rval, finish);

    /* Look up the symbols for each entry */

    for (i = 0, entry_offset = vtable_header_size; 
         i < vtable->entries.nitems; 
         ++i, entry_offset += vtable_entry_size) 
    {
        entry_value = kxld_relocator_get_pointer_at_addr(relocator,
            vtable->vtable, entry_offset);

        /* If we can't find the symbol, it means that the virtual function was
         * defined inline.  There's not much I can do about this; it just means
         * I can't patch this function.
         */
        tmpentry = kxld_array_get_item(&vtable->entries, i);
        sym = kxld_dict_find(defined_cxx_symbols, &entry_value);

        if (sym) {
            tmpentry->patched.name = sym->name;
            tmpentry->patched.addr = sym->link_addr;
        } else {
            tmpentry->patched.name = NULL;
            tmpentry->patched.addr = 0;
        }
    }

    rval = KERN_SUCCESS;
finish:
    return rval;
}
예제 #8
0
void easylink_thread(void *inContext)
{
  OSStatus err = kNoErr;
  mico_Context_t *Context = inContext;
  fd_set readfds;
  struct timeval_t t;
  int reConnCount = 0;

  easylink_log_trace();
  require_action(Context->micoStatus.easylink_sem, threadexit, err = kParamErr);

  
  if(Context->flashContentInRam.micoSystemConfig.easyLinkEnable != false){
    OpenEasylink2_withdata(EasyLink_TimeOut); 
    easylink_log("Start easylink @ %d", mico_get_time());
    mico_rtos_get_semaphore(&Context->micoStatus.easylink_sem, MICO_WAIT_FOREVER);
    if(EasylinkFailed == false)
      _easylinkConnectWiFi(Context);
    else{
      _easylinkStartSoftAp(Context);
      mico_rtos_delete_thread(NULL);
      return;
    }
      
  }else{
    mico_rtos_lock_mutex(&Context->flashContentInRam_mutex);
    Context->flashContentInRam.micoSystemConfig.easyLinkEnable = true;
    MICOUpdateConfiguration(Context);
    mico_rtos_unlock_mutex(&Context->flashContentInRam_mutex);
    _easylinkConnectWiFi_fast(Context);
  }

  err = mico_rtos_get_semaphore(&Context->micoStatus.easylink_sem, ConnectFTC_Timeout);
  require_noerr(err, reboot);

  httpHeader = malloc( sizeof( HTTPHeader_t ) );
  require_action( httpHeader, threadexit, err = kNoMemoryErr );
  HTTPHeaderClear( httpHeader );
  
  t.tv_sec = 100;
  t.tv_usec = 0;
    
  while(1){
    if(Context->micoStatus.easylinkClient_fd == -1){
      err = _connectFTCServer(inContext, &Context->micoStatus.easylinkClient_fd);
      require_noerr(err, Reconn);
    }else{
      FD_ZERO(&readfds);  
      FD_SET(Context->micoStatus.easylinkClient_fd, &readfds);

      err = select(1, &readfds, NULL, NULL, &t);
      require(err > 0, Reconn);
    
      if(FD_ISSET(Context->micoStatus.easylinkClient_fd, &readfds)){
        err = SocketReadHTTPHeader( Context->micoStatus.easylinkClient_fd, httpHeader );

        switch ( err )
        {
          case kNoErr:
            // Read the rest of the HTTP body if necessary
            err = SocketReadHTTPBody( Context->micoStatus.easylinkClient_fd, httpHeader );
            require_noerr(err, Reconn);

            PrintHTTPHeader(httpHeader);
            // Call the HTTPServer owner back with the acquired HTTP header
            err = _FTCRespondInComingMessage( Context->micoStatus.easylinkClient_fd, httpHeader, Context );
            require_noerr( err, Reconn );
            // Reuse HTTPHeader
            HTTPHeaderClear( httpHeader );
          break;

          case EWOULDBLOCK:
              // NO-OP, keep reading
          break;

          case kNoSpaceErr:
            easylink_log("ERROR: Cannot fit HTTPHeader.");
            goto Reconn;
          break;

          case kConnectionErr:
            // NOTE: kConnectionErr from SocketReadHTTPHeader means it's closed
            easylink_log("ERROR: Connection closed.");
            goto threadexit;
             //goto Reconn;
          break;
          default:
            easylink_log("ERROR: HTTP Header parse internal error: %d", err);
            goto Reconn;
        }
      }
    }
    continue;
Reconn:
    HTTPHeaderClear( httpHeader );
    close(Context->micoStatus.easylinkClient_fd);
    Context->micoStatus.easylinkClient_fd = -1;
    require(reConnCount < 6, threadexit);
    reConnCount++;
    sleep(5);
  }  

/*Module is ignored by FTC server, */    
threadexit:
  ConfigWillStop( Context );
  _cleanEasyLinkResource( Context );

  /*Roll back to previous settings (if it has) and reboot*/
  mico_rtos_lock_mutex(&Context->flashContentInRam_mutex);
  if(Context->flashContentInRam.micoSystemConfig.configured != unConfigured){
    Context->flashContentInRam.micoSystemConfig.configured = allConfigured;
    MICOUpdateConfiguration( Context );
    PlatformSoftReboot();
  }
  mico_rtos_unlock_mutex(&Context->flashContentInRam_mutex);


  wifi_power_down();
  Context->micoStatus.easylink_thread_handler = NULL;
  mico_rtos_delete_thread( NULL );
  return;

/*SSID or Password is not correct, module cannot connect to wlan, so reboot and enter EasyLink again*/
reboot:
  ConfigWillStop( Context );
  PlatformSoftReboot();
  return;
}
예제 #9
0
STDMETHODIMP	ExplorerBar::GetBandInfo( DWORD inBandID, DWORD inViewMode, DESKBANDINFO *outInfo )
{
	HRESULT		err;
	
	require_action( outInfo, exit, err = E_INVALIDARG );
	
	mBandID   = inBandID;
	mViewMode = inViewMode;
	
	if( outInfo->dwMask & DBIM_MINSIZE )
	{
		outInfo->ptMinSize.x = 100;
		outInfo->ptMinSize.y = 100;
	}
	if( outInfo->dwMask & DBIM_MAXSIZE )
	{
		// Unlimited max size.
		
		outInfo->ptMaxSize.x = -1;
		outInfo->ptMaxSize.y = -1;
	}
	if( outInfo->dwMask & DBIM_INTEGRAL )
	{
		outInfo->ptIntegral.x = 1;
		outInfo->ptIntegral.y = 1;
	}
	if( outInfo->dwMask & DBIM_ACTUAL )
	{
		outInfo->ptActual.x = 0;
		outInfo->ptActual.y = 0;
	}
	if( outInfo->dwMask & DBIM_TITLE )
	{
		CString		s;
		BOOL		ok;
		
		ok = s.LoadString( IDS_NAME );
		require_action( ok, exit, err = kNoResourcesErr );
		
		#ifdef UNICODE
			lstrcpyn( outInfo->wszTitle, s, sizeof_array( outInfo->wszTitle ) );
		#else
			DWORD		nChars;
			
			nChars = MultiByteToWideChar( CP_ACP, 0, s, -1, outInfo->wszTitle, sizeof_array( outInfo->wszTitle ) );
			err = translate_errno( nChars > 0, (OSStatus) GetLastError(), kUnknownErr );
			require_noerr( err, exit );
		#endif
	}
	if( outInfo->dwMask & DBIM_MODEFLAGS )
	{
		outInfo->dwModeFlags = DBIMF_NORMAL | DBIMF_VARIABLEHEIGHT;
	}
	
	// Force the default background color.
	
	outInfo->dwMask &= ~DBIM_BKCOLOR;
	err = S_OK;
	
exit:
	return( err );
}
예제 #10
0
static OSStatus securetransport(ssl_test_handle * ssl)
{
    OSStatus ortn;
    SSLContextRef ctx = ssl->st;
    SecTrustRef trust = NULL;
    bool got_server_auth = false, got_client_cert_req = false;

    ortn = SSLHandshake(ctx);

    require_action_quiet(ortn==errSSLWouldBlock, out, printf("SSLHandshake failed with err %ld\n", (long)ortn));

    size_t sent, received;
    const char *r=request;
    size_t l=sizeof(request);

    do {
        
        ortn = SSLWrite(ctx, r, l, &sent);
        
        if(ortn == errSSLWouldBlock) {
                r+=sent;
                l-=sent;
        }
        
        if (ortn == errSSLServerAuthCompleted)
        {
            require_string(!got_server_auth, out, "second server auth");
            require_string(!got_client_cert_req, out, "got client cert req before server auth");
            got_server_auth = true;
            require_string(!trust, out, "Got errSSLServerAuthCompleted twice?");
            /* verify peer cert chain */
            require_noerr(SSLCopyPeerTrust(ctx, &trust), out);
            SecTrustResultType trust_result = 0;
            /* this won't verify without setting up a trusted anchor */
            require_noerr(SecTrustEvaluate(trust, &trust_result), out);
        }
    } while(ortn == errSSLWouldBlock || ortn == errSSLServerAuthCompleted);

    //fprintf(stderr, "\nHTTP Request Sent\n");

    require_noerr_action_quiet(ortn, out, printf("SSLWrite failed with err %ld\n", (long)ortn));

    require_string(got_server_auth, out, "never got server auth");

    do {
        ortn = SSLRead(ctx, reply, sizeof(reply)-1, &received);
        //fprintf(stderr, "r"); usleep(1000);
    } while(ortn == errSSLWouldBlock);
    
    //fprintf(stderr, "\n");
    
    require_noerr_action_quiet(ortn, out, printf("SSLRead failed with err %ld\n", (long)ortn));

    reply[received]=0;

    //fprintf(stderr, "HTTP reply:\n");
    //fprintf(stderr, "%s\n",reply);
    
out:
    SSLClose(ctx);
    SSLDisposeContext(ctx);
    if (trust) CFRelease(trust);

    return ortn;
}
예제 #11
0
void micokit_ext_mfg_test(mico_Context_t *inContext)
{
  OSStatus err = kUnknownErr;
  char str[64] = {'\0'};
  char mac[6];
  
  int rgb_led_hue = 0;
  
  uint8_t dht11_ret = 0;
  uint8_t dht11_temp_data = 0;
  uint8_t dht11_hum_data = 0;
  
  int light_ret = 0;
  uint16_t light_sensor_data = 0;
  
  int infrared_ret = 0;
  uint16_t infrared_reflective_data = 0;
  
  int32_t bme280_temp = 0;
  uint32_t bme280_hum = 0;
  uint32_t bme280_press = 0;
  
  UNUSED_PARAMETER(inContext);
  
  mico_rtos_init_semaphore(&mfg_test_state_change_sem, 1); 
  err = MICOAddNotification( mico_notify_WIFI_SCAN_COMPLETED, (void *)mico_notify_WifiScanCompleteHandler );
  require_noerr( err, exit );
  
  while(1){
    switch(mfg_test_module_number){
    case 0:  // mfg mode start
      {
        sprintf(str, "%s\r\nStart:\r\n%s\r\n%s", "TEST MODE", "  next: Key2", "  prev: Key1");
        mf_printf(str);
        while(kNoErr != mico_rtos_get_semaphore(&mfg_test_state_change_sem, MICO_WAIT_FOREVER));
        break;
      }
    case 1:  // OLED
      {
        while(kNoErr != mico_rtos_get_semaphore(&mfg_test_state_change_sem, 0))
        {
          sprintf(str, "%s OLED\r\n", OLED_MFG_TEST_PREFIX);
          mf_printf(str);
          mico_thread_msleep(300);
          
          mf_printf(mfg_test_oled_test_string);
          mico_thread_msleep(300);
        }
        OLED_Clear();
        break;
      }
    case 2:  // RGB_LED
      {
        sprintf(str, "%s RGB LED\r\nBlink: \r\n      R=>G=>B", OLED_MFG_TEST_PREFIX);
        mf_printf(str);
        
        while(kNoErr != mico_rtos_get_semaphore(&mfg_test_state_change_sem, 0))
        {
          hsb2rgb_led_open(rgb_led_hue, 100, 50);
          rgb_led_hue += 120;
          if(rgb_led_hue >= 360){
            rgb_led_hue = 0;
          }
          mico_thread_msleep(300);
        }
        hsb2rgb_led_open(0, 0, 0);
        break;
      }
    case 3: // infrared sensor
      {
        while(kNoErr != mico_rtos_get_semaphore(&mfg_test_state_change_sem, 0))
        {
          infrared_ret = infrared_reflective_read(&infrared_reflective_data);
          if(0 == infrared_ret){ 
            sprintf(str, "%s Infrared\r\nInfrared: %d", OLED_MFG_TEST_PREFIX,
                    infrared_reflective_data);
            mf_printf(str);
          }
          mico_thread_msleep(300);
        }
        break;
      }
    case 4: // DC Motor
      {
        sprintf(str, "%s DC Motor\r\nRun:\r\n     on : 500ms\r\n     off: 500ms", OLED_MFG_TEST_PREFIX);
        mf_printf(str);
        
        while(kNoErr != mico_rtos_get_semaphore(&mfg_test_state_change_sem, 0))
        {
          dc_motor_set(1);
          mico_thread_msleep(500);
          dc_motor_set(0);
          mico_thread_msleep(500);
        }
        dc_motor_set(0);
        break;
      }
    case 5: // BME280
      {
        while(kNoErr != mico_rtos_get_semaphore(&mfg_test_state_change_sem, 0))
        {
          err = bme280_sensor_init();
          if(kNoErr != err){
            sprintf(str, "%s BME280\r\nMoule not found!", OLED_MFG_TEST_PREFIX);
            mf_printf(str);
            // goto next mdoule
            mico_thread_msleep(500);
            mfg_test_module_number = (mfg_test_module_number+1)%(MFG_TEST_MAX_MODULE_NUM+1);
            break;
          }
          else{
            mico_thread_msleep(500);
            err = bme280_data_readout(&bme280_temp, &bme280_press, &bme280_hum);
            if(kNoErr == err){
              sprintf(str, "%s BME280\r\nT: %3.1fC\r\nH: %3.1f%%\r\nP: %5.2fkPa", OLED_MFG_TEST_PREFIX,
                      (float)bme280_temp/100, (float)bme280_hum/1024, (float)bme280_press/1000);
              mf_printf(str);
            }
            else{
              sprintf(str, "%s BME280\r\nRead error!", OLED_MFG_TEST_PREFIX);
              mf_printf(str);
            }
          }
          mico_thread_msleep(500);
        }
        break;
      }
    case 6: // DHT11
      {
        while(kNoErr != mico_rtos_get_semaphore(&mfg_test_state_change_sem, 0))
        {
          dht11_ret = DHT11_Read_Data(&dht11_temp_data, &dht11_hum_data);
          if(0 == dht11_ret){
            sprintf(str, "%s DHT11\r\nT: %3.1fC\r\nH: %3.1f%%", OLED_MFG_TEST_PREFIX,
                    (float)dht11_temp_data, (float)dht11_hum_data);
            mf_printf(str);
          }
          mico_thread_sleep(1);   // DHT11 must >= 1s
        }
        break;
      }
    case 7:   // Light sensor
      {
        while(kNoErr != mico_rtos_get_semaphore(&mfg_test_state_change_sem, 0))
        {
          light_ret = light_sensor_read(&light_sensor_data);
          if(0 == light_ret){
            sprintf(str, "%s Light\r\nLight: %d", OLED_MFG_TEST_PREFIX,
                    light_sensor_data);
            mf_printf(str);
          }
          mico_thread_msleep(300);
        }
        break;
      }
    case 8: // wifi
      {
        wlan_get_mac_address(mac);
        sprintf(str, "%s Wi-Fi\r\nMAC:\r\n    %02X%02X%02X%02X%02X%02X", OLED_MFG_TEST_PREFIX,
                mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]);
        mf_printf(str);
        //mico_thread_msleep(500);
        
        scanap_done = false;
        micoWlanStartScan();
        while((!scanap_done) || (kNoErr != mico_rtos_get_semaphore(&mfg_test_state_change_sem, MICO_WAIT_FOREVER)));
        break;
      }
    default:
      goto exit;  // error
    }
  }
  
exit:
  mico_thread_sleep(MICO_NEVER_TIMEOUT);
}
예제 #12
0
void CSecondPage::OnTvnSelchangedBrowseList(NMHDR *pNMHDR, LRESULT *pResult)
{
	LPNMTREEVIEW					pNMTreeView = reinterpret_cast<LPNMTREEVIEW>(pNMHDR);
	CPrinterSetupWizardSheet	*	psheet;
	Printer						*	printer;
	int								err = 0;

	psheet = reinterpret_cast<CPrinterSetupWizardSheet*>(GetParent());
	require_action( psheet, exit, err = kUnknownErr );

	// The strange code here is to workaround a bug in the CTreeCtrl, whereupon the item
	// we selected isn't passed through correctly to this callback routine.

	if ( !m_gotChoice )
	{
		printer = psheet->GetSelectedPrinter();

		// If we really haven't selected a printer, then re-select NULL and exit

		if ( !printer )
		{
			m_browseList.SelectItem( NULL );

			goto exit;
		}

		// If we already have selected a printer, fake like we've clicked on it, but only
		// if the CTreeCtrl hasn't already selected it
		
		else if ( printer->item != m_browseList.GetSelectedItem() )
		{
			m_gotChoice = true;

			m_browseList.SelectItem( printer->item );

			goto exit;
		}
	}

	HTREEITEM item = m_browseList.GetSelectedItem();
	require_quiet( item, exit );

	printer = reinterpret_cast<Printer*>(m_browseList.GetItemData( item ) );
	require_quiet( printer, exit );

	//
	// this call will trigger a resolve.  When the resolve is complete,
	// our OnResolve will be called.
	//
	err = psheet->StartResolve( printer );
	require_noerr( err, exit );

	//
	// And clear out the printer information box
	//
	SetPrinterInformationState( FALSE );
	m_descriptionField.SetWindowText(L"");
	m_locationField.SetWindowText(L"");

exit:

	if (err != 0)
	{
		CString text;
		CString caption;

		text.LoadString(IDS_ERROR_SELECTING_PRINTER_TEXT);
		caption.LoadString(IDS_ERROR_SELECTING_PRINTER_CAPTION);

		MessageBox(text, caption, MB_OK|MB_ICONEXCLAMATION);
	}

	*pResult = 0;
}
예제 #13
0
void localTcpClient_thread(void *inFd)
{
  OSStatus err;
  int clientFd = *(int *)inFd;
  uint8_t *inDataBuffer = NULL;
  int len;
  int len_temp;
  fd_set readfds;
  fd_set writeSet;
  struct timeval_t t;
  int eventFd = -1;
  mico_queue_t queue;
  socket_msg_t *msg;
  int sent_len, errno;

  inDataBuffer = malloc(wlanBufferLen);
  require_action(inDataBuffer, exit, err = kNoMemoryErr);

  err = socket_queue_create(context, &queue);
  require_noerr( err, exit );
  eventFd = mico_create_event_fd(queue);
  if (eventFd < 0) {
    server_log("create event fd error");
    goto exit_with_queue;
  } 

  t.tv_sec = 4;
  t.tv_usec = 0;
  
  while(1){

    FD_ZERO(&readfds);
    FD_SET(clientFd, &readfds); 
    FD_SET(eventFd, &readfds); 

    select(24, &readfds, NULL, NULL, &t);
    /* send UART data */
    if (FD_ISSET( eventFd, &readfds )) { // have data and can write
        FD_ZERO(&writeSet );
        FD_SET(clientFd, &writeSet );
        t.tv_usec = 100*1000; // max wait 100ms.
        select(1, NULL, &writeSet, NULL, &t);
        if((FD_ISSET( clientFd, &writeSet )) &&
            (kNoErr == mico_rtos_pop_from_queue( &queue, &msg, 0))) {
           sent_len = write(clientFd, msg->data, msg->len);
           if (sent_len <= 0) {
              len = sizeof(errno);
              getsockopt(clientFd, SOL_SOCKET, SO_ERROR, &errno, &len);
              socket_msg_free(msg);
              server_log("write error, fd: %d, errno %d", clientFd, errno );
              if (errno != ENOMEM) {
                  goto exit_with_queue;
              }
           } else {
                  socket_msg_free(msg);
              }
           }
        }

    /*Read data from tcp clients and process these data using HA protocol */ 
    if (FD_ISSET(clientFd, &readfds)) {
      len = recv(clientFd, inDataBuffer, wlanBufferLen, 0);
      len_temp=len;
      tcp_date_num+=len;
      require_action_quiet(len>0, exit_with_queue, err = kConnectionErr);
 //   sppWlanCommandProcess(inDataBuffer, &len, clientFd, context);
      
    //  MicoUartSend(MFG_TEST, inDataBuffer, len_temp);//wcz wcz_add
    }
  }

exit_with_queue:
    len = sizeof(errno);
    getsockopt(clientFd, SOL_SOCKET, SO_ERROR, &errno, &len);
    server_log("Exit: Client exit with err = %d, socket errno %d", err, errno);
    if (eventFd >= 0) {
        mico_delete_event_fd(eventFd);
    }
    socket_queue_delete(context, &queue);
exit:
    SocketClose(&clientFd);
    if(inDataBuffer) free(inDataBuffer);
    mico_rtos_delete_thread(NULL);
    return;
}
OSStatus	USBMIDIDeviceManager::UseDeviceAndInterface(USBDevice *		usbDevice,
														USBInterface *	usbInterface)
{
	// Match the device that was just located with what is in the current state
	MIDIDeviceRef midiDevice = NULL;
	IOUSBDeviceInterface **devIntf = usbDevice->GetPluginInterface();
	const IOUSBDeviceDescriptor *devDesc = usbDevice->GetDeviceDescriptor();
	bool deviceInSetup = false;
	UInt32 vendorProduct = ((UInt32)USBToHostWord(devDesc->idVendor) << 16) | 
							USBToHostWord(devDesc->idProduct);
	CFStringRef serialNumber = usbDevice->GetString(devDesc->iSerialNumber);
	OSStatus err;
	UInt32 locationID;
	require_noerr(err = (*devIntf)->GetLocationID(devIntf, &locationID), errexit);
	{
		// See if it's already in the setup
		MIDIDeviceListRef curDevices = MIDIGetDriverDeviceList(mDriver->Self());
		int nDevices = MIDIDeviceListGetNumberOfDevices(curDevices), firstPass, lastPass;
		if (serialNumber == NULL) {
			firstPass = 2;
			lastPass = 3;
		} else {
			firstPass = 1;
			lastPass = 1;
		}
		
		for (int pass = firstPass; pass <= lastPass && !deviceInSetup; ++pass) {
			// pass 1: match by serial number if present (skipped if not)
			// pass 2: match by locationID
			// pass 3: match by order found
			for (int iDevice = 0; iDevice < nDevices; ++iDevice) {
				SInt32 prevLocation, prevVendorProduct, isOffline;
				midiDevice = MIDIDeviceListGetDevice(curDevices, iDevice);
				err = MIDIObjectGetIntegerProperty(midiDevice, kUSBVendorProductProperty, 
													&prevVendorProduct);
				if (!err && UInt32(prevVendorProduct) == vendorProduct) {
					switch (pass) {
					case 1:
						{
							CFStringRef prevSerial;
							err = MIDIObjectGetStringProperty(midiDevice, kSerialNumberProperty,
																&prevSerial);
							if (!err) {
								if (CFEqual(prevSerial, serialNumber))
									deviceInSetup = true;
								CFRelease(prevSerial);
							}
						}
						break;
					case 2:
						err = MIDIObjectGetIntegerProperty(midiDevice, kUSBLocationProperty, 
															&prevLocation);
						if (!err && UInt32(prevLocation) == locationID)
							deviceInSetup = true;
						break;
					case 3:
						err = MIDIObjectGetIntegerProperty(midiDevice, kMIDIPropertyOffline,
															&isOffline);
						if (!err && isOffline)
							deviceInSetup = true;
						break;
					}
				}
				if (deviceInSetup) break;
			}
		}
		MIDIDeviceListDispose(curDevices);
	}

	if (!deviceInSetup) {
		#if VERBOSE
			printf("creating new device\n");
		#endif
		
		midiDevice = mDriver->CreateDevice(usbDevice, usbInterface);
		require_noerr(err = MIDISetupAddDevice(midiDevice), errexit);
	} else {
		#if VERBOSE
			printf("old device found\n");
		#endif
		mDriver->PreExistingDeviceFound(midiDevice, usbDevice, usbInterface);
	}
	
	// set device properties unconditionally
	MIDIObjectSetIntegerProperty(midiDevice, kUSBVendorProductProperty, vendorProduct);
	MIDIObjectSetIntegerProperty(midiDevice, kUSBLocationProperty, locationID);
	if (serialNumber != NULL)
		MIDIObjectSetStringProperty(midiDevice, kSerialNumberProperty, serialNumber);
	
	// Create a USBMIDIDevice (or subclass), starting it for I/O
	{
		USBMIDIDevice *ioDev = mDriver->CreateUSBMIDIDevice(usbDevice, usbInterface, midiDevice);
		if (ioDev == NULL) goto errexit;
		if (!ioDev->Initialize())
			delete ioDev;
		else {
			if (mUSBMIDIDeviceList.size() == 0)
				mUSBMIDIDeviceList.reserve(4);
			mUSBMIDIDeviceList.push_back(ioDev);
			MIDIObjectSetIntegerProperty(midiDevice, kMIDIPropertyOffline, false);
		}
	}
errexit:
	if (serialNumber != NULL)
		CFRelease(serialNumber);
	return err;
}
예제 #15
0
OSStatus MakeWindowTransparent(WindowRef aWindowRef)
{
    OSStatus status = paramErr;
    require(aWindowRef != NULL, paramErr);

    // is the window compositing or not?
    WindowAttributes attributes;
    status = GetWindowAttributes(aWindowRef, &attributes);
    require_noerr(status, GetWindowAttributes);

    /*	if (attributes & kWindowCompositingAttribute)
    	{
    		// it is compositing so we intercept the kEventWindowGetRegion event to be able to specify an empty opaque region
    		EventTypeSpec wCompositingEvents = { kEventClassWindow, kEventWindowGetRegion };
    		status = InstallWindowEventHandler(aWindowRef, TransparentWindowHandler, 1, &wCompositingEvents, aWindowRef, NULL);
    		require_noerr(status, InstallWindowEventHandler);

    		HIViewRef contentView;
    		status = HIViewFindByID(HIViewGetRoot(aWindowRef), kHIViewWindowContentID, &contentView);
    		require_noerr(status, HIViewFindByID);

    		// and we intercept the kEventControlDraw event of our content view so that we can make it transparent
    		EventTypeSpec cCompositingEvents = { kEventClassControl, kEventControlDraw };
    		status = InstallControlEventHandler(contentView, TransparentWindowHandler, 1, &cCompositingEvents, contentView, NULL);
    		require_noerr(status, InstallControlEventHandler);
    	}
    	else*/
    {
        // it is non-compositing so we intercept the kEventWindowGetRegion event to be able to specify an empty opaque region
        // and we intercept the kEventWindowDrawContent event of our window so that we can make it transparent
        EventTypeSpec wNonCompositingEvents[] =
        {
            { kEventClassWindow, kEventWindowGetRegion },
            { kEventClassWindow, kEventWindowDrawContent }
        };
        status = InstallWindowEventHandler(aWindowRef, TransparentWindowHandler, GetEventTypeCount(wNonCompositingEvents), wNonCompositingEvents, aWindowRef, NULL);
        require_noerr(status, InstallWindowEventHandler);
    }

    // telling the HIToolbox that our window is not opaque so that we will be asked for the opaque region
    UInt32 features;
    status = GetWindowFeatures(aWindowRef, &features);
    require_noerr(status, GetWindowFeatures);
    if ( ( features & kWindowIsOpaque ) != 0 )
    {
        status = HIWindowChangeFeatures(aWindowRef, 0, kWindowIsOpaque);
        require_noerr(status, HIWindowChangeFeatures);
    }

    // force opaque shape to be recalculated
    status = ReshapeCustomWindow(aWindowRef);
    require_noerr(status, ReshapeCustomWindow);

    // ensure that HIToolbox doesn't use standard shadow style, which defeats custom opaque shape
    status = SetWindowAlpha(aWindowRef, 0.999);
    require_noerr(status, SetWindowAlpha);

SetWindowAlpha:
ReshapeCustomWindow:
HIWindowChangeFeatures:
GetWindowFeatures:
InstallControlEventHandler:
HIViewFindByID:
InstallWindowEventHandler:
GetWindowAttributes:
paramErr:

    return status;
}
예제 #16
0
STDMETHODIMP	ExplorerBar::SetSite( IUnknown *inPunkSite )
{
	AFX_MANAGE_STATE( AfxGetStaticModuleState() );
	
	HRESULT		err;
	
	// Release the old interfaces.
	
	if( mWebBrowser )
	{
		mWebBrowser->Release();
		mWebBrowser = NULL;
	}
	if( mSite )
	{
		mSite->Release();
		mSite = NULL;
	}
	
	// A non-NULL site means we're setting the site. Otherwise, the site is being released (done above).
	
	if( !inPunkSite )
	{
		err = S_OK;
		goto exit;
	}
	
	// Get the parent window.
	
	IOleWindow *		oleWindow;
		
	mParentWindow = NULL;
	err = inPunkSite->QueryInterface( IID_IOleWindow, (LPVOID *) &oleWindow );
	require( SUCCEEDED( err ), exit );
	
	err = oleWindow->GetWindow( &mParentWindow );
	oleWindow->Release();
	require_noerr( err, exit );
	require_action( mParentWindow, exit, err = E_FAIL );
	
	// Get the IInputObject interface.
	
	err = inPunkSite->QueryInterface( IID_IInputObjectSite, (LPVOID *) &mSite );
	require( SUCCEEDED( err ), exit );
	check( mSite );
	
	// Get the IWebBrowser2 interface.
	
	IOleCommandTarget *		oleCommandTarget;
	
	err = inPunkSite->QueryInterface( IID_IOleCommandTarget, (LPVOID *) &oleCommandTarget );
	require( SUCCEEDED( err ), exit );
	
	IServiceProvider *		serviceProvider;
	
	err = oleCommandTarget->QueryInterface( IID_IServiceProvider, (LPVOID *) &serviceProvider );
	oleCommandTarget->Release();
	require( SUCCEEDED( err ), exit );
	
	err = serviceProvider->QueryService( SID_SWebBrowserApp, IID_IWebBrowser2, (LPVOID *) &mWebBrowser );
	serviceProvider->Release();
	require( SUCCEEDED( err ), exit );
	
	// Create the main window.
	
	err = SetupWindow();
	require_noerr( err, exit );
	
exit:
	return( err );
}
예제 #17
0
파일: nposx.c 프로젝트: openantz/antz
//-----------------------------------------------------------------------------
FILE* openFileDialog (const char* fileName, int dialogType, void* dataRef)
{																			//zz-osx debug
	FILE* filePtr = NULL;
	
	NavDialogCreationOptions dialogOptions;
	NavDialogRef dialog;
	NavReplyRecord replyRecord;
	CFURLRef fileAsCFURLRef = NULL;
	FSRef fileAsFSRef;
	OSStatus status;
	bool result = false;
	
	unsigned char filePath[1024];
	char msg[4096];
	
	// Get the standard set of defaults
	status = NavGetDefaultDialogCreationOptions (&dialogOptions);
	require_noerr( status, CantGetNavOptions );
	
	// Make the	window app-wide modal
	dialogOptions.modality = kWindowModalityAppModal;
	
	//	dialogOptions.location = fileName;
	
	// Create the dialog
	status = NavCreateGetFileDialog (&dialogOptions, NULL, NULL, NULL, NULL, NULL, &dialog);
	require_noerr( status, CantCreateDialog );
	
	// Show it
	status = NavDialogRun (dialog);
	require_noerr( status, CantRunDialog );
	
	// Get the reply
	status = NavDialogGetReply (dialog, &replyRecord);
	require( ((status == noErr) || (status == userCanceledErr)), CantGetReply );
	
	// If the user clicked "Cancel", just bail
	if ( status == userCanceledErr ) goto UserCanceled;
	
	// Get the file
	status = AEGetNthPtr ( &(replyRecord.selection), 1, typeFSRef, NULL, NULL, &fileAsFSRef, sizeof(FSRef), NULL);
	require_noerr( status, CantExtractFSRef );
	
	// Convert it to a CFURL
	fileAsCFURLRef = CFURLCreateFromFSRef(NULL, &fileAsFSRef);
	
	result = CFURLGetFileSystemRepresentation(fileAsCFURLRef, true, filePath, 1024);
	
	if (!result)
		npPostMsg("err 9824 - cannot convert file dialog path", kNPmsgErr, dataRef);
	else
	{
		// printf ("\nFile Path: %s\n", filePath);
		
		sprintf (msg, "%s", filePath);
		
		filePtr = fopen (msg, "r");
		
		if (filePtr != NULL)
		{
			sprintf (msg, "File Open: %s", filePath);
			npPostMsg (msg, kNPmsgCtrl, dataRef);
		}
		else
			npPostMsg ("err 2995 - File Pointer is NULL", kNPmsgErr, dataRef);
		
		return filePtr;
	}
	
	// Cleanup
CantExtractFSRef:
UserCanceled:
	verify_noerr( NavDisposeReply(&replyRecord) );
CantGetReply:
CantRunDialog:
	NavDialogDispose(dialog);
CantCreateDialog:
CantGetNavOptions:
	// return fileAsCFURLRef;	//part of original sample, does not apply here
	
	return NULL;
}
예제 #18
0
파일: EasyLink.c 프로젝트: FlynnShek/MICO
void easylink_thread(void *inContext)
{
  OSStatus err = kNoErr;
  mico_Context_t *Context = inContext;
  fd_set readfds;
  int reConnCount = 0;
  int clientFdIsSet;

  easylink_log_trace();
  require_action(easylink_sem, threadexit, err = kNotPreparedErr);
      
  if(Context->flashContentInRam.micoSystemConfig.easyLinkByPass == EASYLINK_BYPASS){
    Context->flashContentInRam.micoSystemConfig.easyLinkByPass = EASYLINK_BYPASS_NO;
    MICOUpdateConfiguration(Context);
    _easylinkConnectWiFi_fast(Context);
  }else if(Context->flashContentInRam.micoSystemConfig.easyLinkByPass == EASYLINK_SOFT_AP_BYPASS){
    ConfigWillStop( Context );
    _easylinkStartSoftAp(Context);
    mico_rtos_delete_thread(NULL);
    return;
  }else{
#ifdef EasyLink_Plus
    easylink_log("Start easylink plus mode");
    micoWlanStartEasyLinkPlus(EasyLink_TimeOut/1000);
#else
    easylink_log("Start easylink V2");
    micoWlanStartEasyLink(EasyLink_TimeOut/1000);
#endif 
    mico_rtos_get_semaphore(&easylink_sem, MICO_WAIT_FOREVER);
    if(EasylinkFailed == false)
      _easylinkConnectWiFi(Context);
    else{
      msleep(20);
      _cleanEasyLinkResource( Context );
      ConfigWillStop( Context );
      _easylinkStartSoftAp(Context);
      mico_rtos_delete_thread(NULL);
      return;
    }
  }

  err = mico_rtos_get_semaphore(&easylink_sem, EasyLink_ConnectWlan_Timeout);
  require_noerr(err, reboot);

  httpHeader = HTTPHeaderCreate();
  require_action( httpHeader, threadexit, err = kNoMemoryErr );
  HTTPHeaderClear( httpHeader );
    
  while(1){
    if(easylinkClient_fd == -1){
      err = _connectFTCServer(inContext, &easylinkClient_fd);
      require_noerr(err, Reconn);
    }else{
      FD_ZERO(&readfds);  
      FD_SET(easylinkClient_fd, &readfds);

      if(httpHeader->len == 0){
        err = select(1, &readfds, NULL, NULL, NULL);
        require(err>=1, threadexit);
        clientFdIsSet = FD_ISSET(easylinkClient_fd, &readfds);
      }
  
      if(clientFdIsSet||httpHeader->len){
        err = SocketReadHTTPHeader( easylinkClient_fd, httpHeader );

        switch ( err )
        {
          case kNoErr:
            // Read the rest of the HTTP body if necessary
            do{
              err = SocketReadHTTPBody( easylinkClient_fd, httpHeader );
              require_noerr(err, Reconn);

              PrintHTTPHeader(httpHeader);
              // Call the HTTPServer owner back with the acquired HTTP header
              err = _FTCRespondInComingMessage( easylinkClient_fd, httpHeader, Context );
              require_noerr( err, Reconn );
              if(httpHeader->contentLength == 0)
                break;
            } while( httpHeader->chunkedData == true || httpHeader->dataEndedbyClose == true);
              // Reuse HTTPHeader
              HTTPHeaderClear( httpHeader );
          break;

          case EWOULDBLOCK:
              // NO-OP, keep reading
          break;

          case kNoSpaceErr:
            easylink_log("ERROR: Cannot fit HTTPHeader.");
            goto Reconn;

          case kConnectionErr:
            // NOTE: kConnectionErr from SocketReadHTTPHeader means it's closed
            easylink_log("ERROR: Connection closed.");
              /*Roll back to previous settings (if it has) and reboot*/
            if(Context->flashContentInRam.micoSystemConfig.configured == wLanUnConfigured ){
              Context->flashContentInRam.micoSystemConfig.configured = allConfigured;
              MICOUpdateConfiguration( Context );
              MicoSystemReboot();
            }else{
              micoWlanPowerOff();
              msleep(20);
            }
            goto threadexit;

          default:
            easylink_log("ERROR: HTTP Header parse internal error: %d", err);
            goto Reconn;
        }
      }
    }
    continue;
Reconn:
    HTTPHeaderClear( httpHeader );
    SocketClose(&easylinkClient_fd);
    easylinkClient_fd = -1;
    require(reConnCount < 6, reboot);
    reConnCount++;
    sleep(5);
  }  

/*Module is ignored by FTC server, */    
threadexit:
  _cleanEasyLinkResource( Context );
  ConfigWillStop( Context );
  mico_rtos_delete_thread( NULL );
  return;
  
/*SSID or Password is not correct, module cannot connect to wlan, so reboot and enter EasyLink again*/
reboot:
  MicoSystemReboot();
  return;
}
예제 #19
0
파일: kxld_vtable.c 프로젝트: Algozjb/xnu
/*******************************************************************************
* Initializes a vtable object by matching up relocation entries to the vtable's
* entries and finding the corresponding symbols.
*******************************************************************************/
static kern_return_t
init_by_relocs(KXLDVTable *vtable, const KXLDSym *vtable_sym, 
    const KXLDSect *sect, const KXLDRelocator *relocator)
{
    kern_return_t rval = KERN_FAILURE;
    KXLDReloc *reloc = NULL;
    KXLDVTableEntry *entry = NULL;
    KXLDSym *sym = NULL;
    kxld_addr_t vtable_base_offset = 0;
    kxld_addr_t entry_offset = 0;
    u_int i = 0;
    u_int nentries = 0;
    u_int vtable_entry_size = 0;
    u_int vtable_header_size = 0;
    u_int base_reloc_index = 0;
    u_int reloc_index = 0;

    check(vtable);
    check(vtable_sym);
    check(sect);
    check(relocator);

    /* Find the first entry past the vtable padding */

    (void) get_vtable_base_sizes(relocator->is_32_bit, 
        &vtable_entry_size, &vtable_header_size);

    vtable_base_offset = kxld_sym_get_section_offset(vtable_sym, sect) + 
        vtable_header_size;
   
    /* Find the relocation entry at the start of the vtable */

    rval = kxld_reloc_get_reloc_index_by_offset(&sect->relocs, 
        vtable_base_offset, &base_reloc_index);
    require_noerr(rval, finish);

    /* Count the number of consecutive relocation entries to find the number of
     * vtable entries.  For some reason, the __TEXT,__const relocations are
     * sorted in descending order, so we have to walk backwards.  Also, make
     * sure we don't run off the end of the section's relocs.
     */

    reloc_index = base_reloc_index;
    entry_offset = vtable_base_offset;
    reloc = kxld_array_get_item(&sect->relocs, reloc_index);
    while (reloc->address == entry_offset) {
        ++nentries;
        if (!reloc_index) break;

        --reloc_index;

        reloc = kxld_array_get_item(&sect->relocs, reloc_index);
        entry_offset += vtable_entry_size;
    }

    /* Allocate the symbol index */

    rval = kxld_array_init(&vtable->entries, sizeof(KXLDVTableEntry), nentries);
    require_noerr(rval, finish);

    /* Find the symbols for each vtable entry */

    for (i = 0; i < vtable->entries.nitems; ++i) {
        reloc = kxld_array_get_item(&sect->relocs, base_reloc_index - i);
        entry = kxld_array_get_item(&vtable->entries, i);

        /* If we can't find a symbol, it means it is a locally-defined,
         * non-external symbol that has been stripped.  We don't patch over
         * locally-defined symbols, so we leave the symbol as NULL and just
         * skip it.  We won't be able to patch subclasses with this symbol,
         * but there isn't much we can do about that.
         */
        sym = kxld_reloc_get_symbol(relocator, reloc, sect->data);

        entry->unpatched.sym = sym;
        entry->unpatched.reloc = reloc;
    }

    rval = KERN_SUCCESS;
finish:
    return rval;
}
예제 #20
0
파일: EasyLink.c 프로젝트: FlynnShek/MICO
OSStatus _FTCRespondInComingMessage(int fd, HTTPHeader_t* inHeader, mico_Context_t * const inContext)
{
    OSStatus err = kUnknownErr;
    const char *        value;
    size_t              valueSize;

    easylink_log_trace();

    switch(inHeader->statusCode){
      case kStatusAccept:
        easylink_log("Easylink server accepted!");
        err = kNoErr;
        goto exit;

      case kStatusOK:
        easylink_log("Easylink server respond status OK!");
        err = HTTPGetHeaderField( inHeader->buf, inHeader->len, "Content-Type", NULL, NULL, &value, &valueSize, NULL );
        require_noerr(err, exit);
        if( strnicmpx( value, valueSize, kMIMEType_JSON ) == 0 ){
          easylink_log("Receive JSON config data!");
          err = ConfigIncommingJsonMessage( inHeader->extraDataPtr, inContext);
          inContext->flashContentInRam.micoSystemConfig.configured = allConfigured;
          err = MICOUpdateConfiguration(inContext);
          SocketClose(&fd);
          inContext->micoStatus.sys_state = eState_Software_Reset;
          require(inContext->micoStatus.sys_state_change_sem, exit);
          mico_rtos_set_semaphore(&inContext->micoStatus.sys_state_change_sem);
          mico_thread_sleep(MICO_WAIT_FOREVER);
        }
#ifdef MICO_FLASH_FOR_UPDATE
        else if(strnicmpx( value, valueSize, kMIMEType_MXCHIP_OTA ) == 0){
          easylink_log("Receive OTA data!");
          mico_rtos_lock_mutex(&inContext->flashContentInRam_mutex);
          memset(&inContext->flashContentInRam.bootTable, 0, sizeof(boot_table_t));
          inContext->flashContentInRam.bootTable.length = inHeader->contentLength;
          inContext->flashContentInRam.bootTable.start_address = UPDATE_START_ADDRESS;
          inContext->flashContentInRam.bootTable.type = 'A';
          inContext->flashContentInRam.bootTable.upgrade_type = 'U';
          inContext->flashContentInRam.micoSystemConfig.easyLinkByPass = EASYLINK_BYPASS;
          MICOUpdateConfiguration(inContext);
          mico_rtos_unlock_mutex(&inContext->flashContentInRam_mutex);
          SocketClose(&fd);
          inContext->micoStatus.sys_state = eState_Software_Reset;
          require(inContext->micoStatus.sys_state_change_sem, exit);
          mico_rtos_set_semaphore(&inContext->micoStatus.sys_state_change_sem);
          mico_thread_sleep(MICO_WAIT_FOREVER);
        }
#endif
        else{
          return kUnsupportedDataErr;
        }
        err = kNoErr;
        goto exit;
        
      default:
        goto exit;
    }

 exit:
    return err;

}
예제 #21
0
파일: kxld_vtable.c 프로젝트: Algozjb/xnu
/*******************************************************************************
* Initializes vtables by performing a reverse lookup on symbol values when
* they exist in the vtable entry, and by looking through a matching relocation
* entry when the vtable entry is NULL.
*
* Final linked images require this hybrid vtable initialization approach
* because they are already internally resolved.  This means that the vtables
* contain valid entries to local symbols, but still have relocation entries for
* external symbols.
*******************************************************************************/
static kern_return_t
init_by_entries_and_relocs(KXLDVTable *vtable, const KXLDSym *vtable_sym, 
    const KXLDRelocator *relocator, const KXLDArray *relocs,
    const KXLDDict *defined_cxx_symbols)
{
    kern_return_t rval = KERN_FAILURE;
    KXLDReloc *reloc = NULL;
    KXLDVTableEntry *tmpentry = NULL;
    KXLDSym *sym = NULL;
    u_int vtable_entry_size = 0;
    u_int vtable_header_size = 0;
    kxld_addr_t entry_value = 0;
    u_long entry_offset = 0;
    u_int nentries = 0;
    u_int i = 0;
    char *demangled_name1 = NULL;
    size_t demangled_length1 = 0;

    check(vtable);
    check(vtable_sym);
    check(relocator);
    check(relocs);

    /* Find the first entry and its offset past the vtable padding */

    (void) get_vtable_base_sizes(relocator->is_32_bit, 
        &vtable_entry_size, &vtable_header_size);

    /* In a final linked image, a vtable slot is valid if it is nonzero
     * (meaning the userspace linker has already resolved it) or if it has
     * a relocation entry.  We'll know the end of the vtable when we find a
     * slot that meets neither of these conditions.
     */
    entry_offset = vtable_header_size;
    while (1) {
        entry_value = kxld_relocator_get_pointer_at_addr(relocator,
            vtable->vtable, entry_offset);
        if (!entry_value) {
            reloc = kxld_reloc_get_reloc_by_offset(relocs, 
                vtable_sym->base_addr + entry_offset);
            if (!reloc) break;
        }

        ++nentries;
        entry_offset += vtable_entry_size;
    }

    /* Allocate the symbol index */

    rval = kxld_array_init(&vtable->entries, sizeof(KXLDVTableEntry), nentries);
    require_noerr(rval, finish);

    /* Find the symbols for each vtable entry */

    for (i = 0, entry_offset = vtable_header_size; 
         i < vtable->entries.nitems; 
         ++i, entry_offset += vtable_entry_size) 
    {
        entry_value = kxld_relocator_get_pointer_at_addr(relocator,
            vtable->vtable, entry_offset);

        /* If we can't find a symbol, it means it is a locally-defined,
         * non-external symbol that has been stripped.  We don't patch over
         * locally-defined symbols, so we leave the symbol as NULL and just
         * skip it.  We won't be able to patch subclasses with this symbol,
         * but there isn't much we can do about that.
         */
        if (entry_value) {
            reloc = NULL;
            sym = kxld_dict_find(defined_cxx_symbols, &entry_value);
        } else {
            reloc = kxld_reloc_get_reloc_by_offset(relocs,
                vtable_sym->base_addr + entry_offset);
            require_action(reloc, finish,
                rval=KERN_FAILURE;
                kxld_log(kKxldLogPatching, kKxldLogErr, 
                    kKxldLogMalformedVTable, 
                    kxld_demangle(vtable->name, &demangled_name1, 
                        &demangled_length1)));
        
            sym = kxld_reloc_get_symbol(relocator, reloc, /* data */ NULL);
        }

        tmpentry = kxld_array_get_item(&vtable->entries, i);
        tmpentry->unpatched.reloc = reloc;
        tmpentry->unpatched.sym = sym;
    }

    rval = KERN_SUCCESS;
finish:
    return rval;
}
예제 #22
0
파일: main.c 프로젝트: arnelh/Examples
int main()
{
    IBNibRef 		nibRef;
    WindowRef 		window;
    OSStatus		err;
	MenuDefSpec		defSpec;
	MenuRef			menu;
	SInt32			gestaltResult;

    // Create a Nib reference passing the name of the nib file (without the .nib extension)
    // CreateNibReference only searches into the application bundle.
    err = CreateNibReference(CFSTR("main"), &nibRef);
    require_noerr( err, CantGetNibRef );
    
    // Once the nib reference is created, set the menu bar. "MainMenu" is the name of the menu bar
    // object. This name is set in InterfaceBuilder when the nib is created.
    err = SetMenuBarFromNib(nibRef, CFSTR("MenuBar"));
    require_noerr( err, CantSetMenuBar );
    
    // Add a Quit item if we're not running on X
    Gestalt( gestaltMenuMgrAttr, &gestaltResult );
    if ( ( gestaltResult & gestaltMenuMgrAquaLayoutMask ) == 0 )
    {
    	MenuRef rootMenu = AcquireRootMenu();
    	MenuItemIndex item;
    	
    	GetMenuItemHierarchicalMenu( rootMenu, 2, &menu );
    	AppendMenuItemTextWithCFString( menu, CFSTR("Quit"), 0, kHICommandQuit, &item );
    	SetMenuItemCommandKey( menu, item, false, 'Q' );
    	
    	ReleaseMenu( rootMenu );
    }
    
	defSpec.defType = kMenuDefProcPtr;
	defSpec.u.defProc = NewMenuDefUPP( SampleMDEF );
	
	// Create a standard menu
	CreateNewMenu( 200, 0, &menu );
	SetMenuTitleWithCFString( menu, CFSTR("Sample") );
	InsertMenu( menu, 0 );
	AddSampleItems( menu );
	
	// Create a custom menu
	CreateCustomMenu( &defSpec, 201, 0, &menu );
	SetMenuTitleWithCFString( menu, CFSTR("Sample [Custom]") );
	InsertMenu( menu, 0 );
	AddSampleItems( menu );
	
	// Create a standard menu
	CreateNewMenu( 202, 0, &menu );
	SetMenuTitleWithCFString( menu, CFSTR("Shell") );
	InsertMenu( menu, 0 );
	AddShellItems( menu );
	
	// Create a custom menu
	CreateCustomMenu( &defSpec, 203, 0, &menu );
	SetMenuTitleWithCFString( menu, CFSTR("Shell [Custom]") );
	InsertMenu( menu, 0 );
	AddShellItems( menu );
	
	// Create a standard menu
	CreateNewMenu( 204, 0, &menu );
	SetMenuTitleWithCFString( menu, CFSTR("Fonts") );
	InsertMenu( menu, 0 );
	CreateStandardFontMenu( menu, 0, 0, 0, NULL );
	
	// Create a custom menu
	CreateCustomMenu( &defSpec, 205, 0, &menu );
	SetMenuTitleWithCFString( menu, CFSTR("Fonts [Custom]") );
	InsertMenu( menu, 0 );
	CreateStandardFontMenu( menu, 0, 0, 0, NULL );
	
    // Then create a window. "MainWindow" is the name of the window object. This name is set in 
    // InterfaceBuilder when the nib is created.
    err = CreateWindowFromNib(nibRef, CFSTR("MainWindow"), &window);
    require_noerr( err, CantCreateWindow );

    // We don't need the nib reference anymore.
    DisposeNibReference(nibRef);
    
    // The window was created hidden so show it.
    ShowWindow( window );
    
    // Call the event loop
    RunApplicationEventLoop();

CantCreateWindow:
CantSetMenuBar:
CantGetNibRef:
	return err;
}
예제 #23
0
OSStatus fogCloudDevFirmwareUpdate(app_context_t* const inContext,
                                   MVDOTARequestData_t devOTARequestData)
{
    cloud_if_log_trace();
    OSStatus err = kUnknownErr;
    ecs_ota_flash_params_t ota_flash_params =
    {
        MICO_PARTITION_OTA_TEMP,
        0x0,
    };

    md5_context md5;
    unsigned char md5_16[16] = {0};
    char *pmd5_32 = NULL;
    char rom_file_md5[32] = {0};
    uint8_t data[SizePerRW] = {0};
    uint32_t updateStartAddress = 0;
    uint32_t readLength = 0;
    uint32_t i = 0, size = 0;
    uint32_t romStringLen = 0;

    // crc16
    CRC16_Context contex;

    cloud_if_log("fogCloudDevFirmwareUpdate: start ...");

    //get latest rom version, file_path, md5
    cloud_if_log("fogCloudDevFirmwareUpdate: get latest rom version from server ...");
    err = FogCloudGetLatestRomVersion(&easyCloudContext);
    require_noerr_action( err, exit_with_error, cloud_if_log("ERROR: FogCloudGetLatestRomVersion failed! err=%d", err) );

    //FW version compare
    cloud_if_log("currnt_version=%s", inContext->appConfig->fogcloudConfig.romVersion);
    cloud_if_log("latestRomVersion=%s", easyCloudContext.service_status.latestRomVersion);
    cloud_if_log("bin_file=%s", easyCloudContext.service_status.bin_file);
    cloud_if_log("bin_md5=%s", easyCloudContext.service_status.bin_md5);

    romStringLen = strlen(easyCloudContext.service_status.latestRomVersion) > strlen(inContext->appConfig->fogcloudConfig.romVersion) ?
                   strlen(easyCloudContext.service_status.latestRomVersion):strlen(inContext->appConfig->fogcloudConfig.romVersion);
    if(0 == strncmp(inContext->appConfig->fogcloudConfig.romVersion,
                    easyCloudContext.service_status.latestRomVersion,
                    romStringLen))
    {
        cloud_if_log("the current firmware version[%s] is up-to-date!",
                     inContext->appConfig->fogcloudConfig.romVersion);
        inContext->appStatus.fogcloudStatus.RecvRomFileSize = 0;
        err = kNoErr;
        goto exit_with_no_error;
    }
    cloud_if_log("fogCloudDevFirmwareUpdate: new firmware[%s] found on server, downloading ...",
                 easyCloudContext.service_status.latestRomVersion);

    inContext->appStatus.fogcloudStatus.isOTAInProgress = true;
    OTAWillStart(inContext);

    //get rom data
    err = FogCloudGetRomData(&easyCloudContext, ota_flash_params);
    require_noerr_action( err, exit_with_error,
                          cloud_if_log("ERROR: FogCloudGetRomData failed! err=%d", err) );

//------------------------------ OTA DATA VERIFY -----------------------------
    // md5 init
    InitMd5(&md5);
    CRC16_Init( &contex );
    memset(rom_file_md5, 0, 32);
    memset(data, 0xFF, SizePerRW);
    updateStartAddress = ota_flash_params.update_offset;
    size = (easyCloudContext.service_status.bin_file_size)/SizePerRW;

    // read flash, md5 update
    for(i = 0; i <= size; i++)
    {
        if( i == size )
        {
            if( (easyCloudContext.service_status.bin_file_size)%SizePerRW )
            {
                readLength = (easyCloudContext.service_status.bin_file_size)%SizePerRW;
            }
            else
            {
                break;
            }
        }
        else
        {
            readLength = SizePerRW;
        }
        err = MicoFlashRead(ota_flash_params.update_partion, &updateStartAddress, data, readLength);
        require_noerr(err, exit_with_error);
        Md5Update(&md5, (uint8_t *)data, readLength);
        CRC16_Update( &contex, data, readLength );
    }

// read done, calc MD5
    Md5Final(&md5, md5_16);
    CRC16_Final( &contex, &ota_crc );
    pmd5_32 = ECS_DataToHexStringLowercase(md5_16,  sizeof(md5_16));  //convert hex data to hex string
    cloud_if_log("ota_data_in_flash_md5[%d]=%s", strlen(pmd5_32), pmd5_32);

    if (NULL != pmd5_32)
    {
        strncpy(rom_file_md5, pmd5_32, strlen(pmd5_32));
        free(pmd5_32);
        pmd5_32 = NULL;
    }
    else
    {
        err = kNoMemoryErr;
        goto exit_with_error;
    }

    // check md5
    if(0 != strncmp( easyCloudContext.service_status.bin_md5, (char*)&(rom_file_md5[0]),
                     strlen( easyCloudContext.service_status.bin_md5)))
    {
        cloud_if_log("ERROR: ota data wrote in flash md5 checksum err!!!");
        err = kChecksumErr;
        goto exit_with_error;
    }
    else
    {
        cloud_if_log("OTA data in flash md5 check success, crc16=%d.", ota_crc);
    }
    //----------------------------------------------------------------------------

    //update rom version in flash
    cloud_if_log("fogCloudDevFirmwareUpdate: return rom version && file size.");
    mico_rtos_lock_mutex(&inContext->mico_context->flashContentInRam_mutex);
    memset(inContext->appConfig->fogcloudConfig.romVersion,
           0, MAX_SIZE_FW_VERSION);
    strncpy(inContext->appConfig->fogcloudConfig.romVersion,
            easyCloudContext.service_status.latestRomVersion,
            strlen(easyCloudContext.service_status.latestRomVersion));
    inContext->appStatus.fogcloudStatus.RecvRomFileSize = easyCloudContext.service_status.bin_file_size;
    err = mico_system_context_update(inContext->mico_context);
    mico_rtos_unlock_mutex(&inContext->mico_context->flashContentInRam_mutex);

    OTASuccess(inContext);
    err = kNoErr;
    goto exit_with_no_error;

exit_with_no_error:
    cloud_if_log("fogCloudDevFirmwareUpdate exit with no error.");
    inContext->appStatus.fogcloudStatus.isOTAInProgress = false;
    return err;

exit_with_error:
    cloud_if_log("fogCloudDevFirmwareUpdate exit with err=%d.", err);
    OTAFailed(inContext);
    inContext->appStatus.fogcloudStatus.isOTAInProgress = false;
    return err;
}
예제 #24
0
/* property notify check
* description: check update of all properties in notify list, 
*              if notify list is not created, create is first from service_table.
* input: mico context;
*        service table
* output: json object contains properties updated, like {k:v, k:v}
*         if no update or error, return NULL
* return: kNoErr if succeed.
*/
OSStatus mico_properties_notify_check(mico_Context_t * const inContext, struct mico_service_t *service_table,
                                      json_object* notify_obj)
{
  OSStatus err = kNoErr;
  int s_idx = 0; 
  int p_idx = 0;
  int iid = 0;
  char iid_str[16] = {0};
  int ret = 0;
  mico_prop_notify_node_t *_notify_list = NULL;
  
  require_action(inContext, exit, err = kParamErr);
  require_action(service_table, exit, err = kParamErr);
  require_action(notify_obj, exit, err = kParamErr);
  
  //properties_log("properties update check...");
  
  // if notify list not created, create it the first time
  if(!notify_list_inited){
    if(NULL != g_notify_list){
      PropertyNotifyListClean(&g_notify_list);  // clean g_notify_list  
    }
    err = create_notify_list(service_table, &g_notify_list);
    require_noerr(err, exit);
    notify_list_inited = true;
  }
  
  _notify_list = g_notify_list;
  // search notify list
  while(getNextNotify(_notify_list, &iid, &s_idx, &p_idx, &_notify_list) == kNoErr){
    //properties_log("notify prop check: iid=%d, s_idx=%d, p_idx=%d.", iid, s_idx, p_idx);
    // get key string
    memset((void*)iid_str, '\0', sizeof(iid_str));
    Int2Str((uint8_t*)iid_str, iid);
    
    // add updated property to json object
    if((NULL != service_table[s_idx].properties[p_idx].event) &&
       (*(service_table[s_idx].properties[p_idx].event)) ){  // prop event enable
         // do prop update check && update prop value && len
         ret = service_table[s_idx].properties[p_idx].notify_check(&(service_table[s_idx].properties[p_idx]), 
                                                                   service_table[s_idx].properties[p_idx].arg, 
                                                                   service_table[s_idx].properties[p_idx].value, 
                                                                   service_table[s_idx].properties[p_idx].value_len);
         if(1 == ret){  // prop updated, add new value to notify json object
           switch(service_table[s_idx].properties[p_idx].format){
           case MICO_PROP_TYPE_INT:{
             json_object_object_add(notify_obj, iid_str, 
                                    json_object_new_int(*((int*)(service_table[s_idx].properties[p_idx].value))));
             break;
           }
           case MICO_PROP_TYPE_FLOAT:{
             json_object_object_add(notify_obj, iid_str, 
                                    json_object_new_double(*((float*)service_table[s_idx].properties[p_idx].value)));
             break;
           }
           case MICO_PROP_TYPE_STRING:{
             json_object_object_add(notify_obj, iid_str, 
                                    json_object_new_string((char*)service_table[s_idx].properties[p_idx].value));
             break;
           }
           case MICO_PROP_TYPE_BOOL:{
             json_object_object_add(notify_obj, iid_str, 
                                    json_object_new_boolean(*((bool*)service_table[s_idx].properties[p_idx].value)));
             break;
           }
           default:
             properties_log("ERROR: prop format unsupport!");
             break;
           }
         }
       }
  }
  
exit:
  return err;
}
예제 #25
0
int SocketReadHTTPHeader( int inSock, HTTPHeader_t *inHeader )
{
    int        err =0;
    char *          buf;
    char *          dst;
    char *          lim;
    char *          end;
    size_t          len;
    ssize_t         n;

    buf = inHeader->buf;
    dst = buf + inHeader->len;
    lim = buf + sizeof( inHeader->buf );
    for( ;; )
    {
        if(findHeader( inHeader,  &end ))
            break ;
        n = read( inSock, dst, (size_t)( lim - dst ) );
        if(      n  > 0 ) len = (size_t) n;
        else  {
            err = kConnectionErr;
            goto exit;
        }
        dst += len;
        inHeader->len += len;
    }

    inHeader->len = (size_t)( end - buf );
    err = HTTPHeaderParse( inHeader );
    require_noerr( err, exit );
    inHeader->extraDataLen = (size_t)( dst - end );
    if(inHeader->extraDataPtr) {
        free((uint8_t *)inHeader->extraDataPtr);
        inHeader->extraDataPtr = 0;
    }

    /* For chunked extra data without content length */
    if(inHeader->chunkedData == true) {
        inHeader->chunkedDataBufferLen = (inHeader->extraDataLen > READ_LENGTH)? inHeader->extraDataLen:READ_LENGTH;
        inHeader->chunkedDataBufferPtr = calloc(inHeader->chunkedDataBufferLen, sizeof(uint8_t)); //Make extra data buffer larger than chunk length
        require_action(inHeader->chunkedDataBufferPtr, exit, err = kNoMemoryErr);
        memcpy((uint8_t *)inHeader->chunkedDataBufferPtr, end, inHeader->extraDataLen);
        inHeader->extraDataPtr = inHeader->chunkedDataBufferPtr;
        return kNoErr;
    }

    /* Extra data with content length */

    if (inHeader->contentLength != 0) { //Content length >0, create a memory buffer (Content length) and store extra data
        size_t copyDataLen = (inHeader->contentLength >= inHeader->extraDataLen)? inHeader->extraDataLen : inHeader->contentLength;
        if(inHeader->onReceivedDataCallback && (inHeader->onReceivedDataCallback)(inHeader, 0, (uint8_t *)end, copyDataLen, inHeader->userContext)==kNoErr) {
            inHeader->isCallbackSupported = true;
            inHeader->extraDataPtr = calloc(READ_LENGTH, sizeof(uint8_t));
            require_action(inHeader->extraDataPtr, exit, err = kNoMemoryErr);
        } else {
            inHeader->isCallbackSupported = false;
            inHeader->extraDataPtr = calloc(inHeader->contentLength , sizeof(uint8_t));
            require_action(inHeader->extraDataPtr, exit, err = kNoMemoryErr);
            memcpy((uint8_t *)inHeader->extraDataPtr, end, copyDataLen);
        }
        err = kNoErr;
    } /* Extra data without content length, data is ended by conntection close */
    // else if(inHeader->extraDataLen != 0){ //Content length =0, but extra data length >0, create a memory buffer (1500)and store extra data
    //   inHeader->dataEndedbyClose = true;
    //   inHeader->extraDataPtr = calloc(1500, sizeof(uint8_t));
    //   require_action(inHeader->extraDataPtr, exit, err = kNoMemoryErr);
    //   memcpy((uint8_t *)inHeader->extraDataPtr, end, inHeader->extraDataLen);
    //   (inHeader->onReceivedDataCallback)(inHeader, 0, (uint8_t *)inHeader->extraDataPtr, inHeader->extraDataLen, inHeader->userContext);

    //   err = kNoErr;
    // }
    else
        return kNoErr;

exit:
    return err;
}
예제 #26
0
OSStatus _property_write_create_response(struct mico_service_t *service_table, 
                                    char *key, json_object *val,
                                    json_object *out_write_obj, json_object *out_err_prop_obj)
{
  OSStatus err = kUnknownErr;
  int iid = 0;
  int service_index = 0;
  int property_index = 0;
  int ret = 0;
  
  int int_value = 0;
  float float_value = 0;
  bool boolean_value = false;
  const char *set_string = NULL;
  int set_string_len = 0;
  
  require_action(service_table, exit, err = kParamErr);
  require_action(key, exit, err = kParamErr);
  require_action(val, exit, err = kParamErr);
  require_action(out_write_obj, exit, err = kParamErr);
  require_action(out_err_prop_obj, exit, err = kParamErr);
  
  Str2Int((uint8_t*)key, &iid);
  //properties_log("properties write iid=%d.", iid);
  
  err = FindPropertyByIID(service_table, iid, &service_index, &property_index);
  require_noerr(err, exit);
  
  if( MICO_PROP_PERMS_WRITABLE (service_table[service_index].properties[property_index].perms) ){
    switch(service_table[service_index].properties[property_index].format){
    case MICO_PROP_TYPE_INT:{
      //properties_log("prop got: %s, iid=%d, value=%d", 
      //               service_table[service_index].properties[property_index].type, iid, 
      //               *((int*)service_table[service_index].properties[property_index].value));
      // property set (hardware operation)
      if(NULL != service_table[service_index].properties[property_index].set){
        int_value = json_object_get_int(val);
        ret = service_table[service_index].properties[property_index].set(&service_table[service_index].properties[property_index],
                                                                          service_table[service_index].properties[property_index].arg,
                                                                          (void*)&int_value, sizeof(int));
        if (0 == ret){  // set ok, update property value
          *((int*)service_table[service_index].properties[property_index].value) =  int_value;
          json_object_object_add(out_write_obj, key, json_object_new_int(int_value));
          err = kNoErr;
        }
        else{  // return write err status
          json_object_object_add(out_err_prop_obj, key, json_object_new_int(MICO_PROP_CODE_WRITE_FAILED));
          err = kWriteErr;
        }
      }
      else{ // no set func err
        json_object_object_add(out_err_prop_obj, key, json_object_new_int(MICO_PROP_CODE_NO_SET_FUNC));
        err = kWriteErr;
      }
      break;
    }
    case MICO_PROP_TYPE_FLOAT:{
      //properties_log("prop got: %s, iid=%d, value=%f", 
      //               service_table[service_index].properties[property_index].type, iid, 
      //               *((float*)service_table[service_index].properties[property_index].value));
      // property set(hardware operation)
      if(NULL != service_table[service_index].properties[property_index].set){
        float_value = json_object_get_double(val);
        ret = service_table[service_index].properties[property_index].set(&service_table[service_index].properties[property_index], 
                                                                          service_table[service_index].properties[property_index].arg,
                                                                          (void*)&float_value, sizeof(float));
        if (0 == ret){  // set ok, update property value
          *((float*)service_table[service_index].properties[property_index].value) = float_value;
          json_object_object_add(out_write_obj, key, json_object_new_double(float_value));
          err = kNoErr;
        }
        else{  // return write err status
          json_object_object_add(out_err_prop_obj, key, json_object_new_int(MICO_PROP_CODE_WRITE_FAILED));
          err = kWriteErr;
        }
      }
      else{ // no set func err
        json_object_object_add(out_err_prop_obj, key, json_object_new_int(MICO_PROP_CODE_NO_SET_FUNC));
        err = kWriteErr;
      }
      break;
    }
    case MICO_PROP_TYPE_STRING:{
      //properties_log("prop got: %s, iid=%d, value=%s", 
      //               service_table[service_index].properties[property_index].type, iid, 
      //               (char*)service_table[service_index].properties[property_index].value);
      
      // property set(hardware operation)
      if(NULL != service_table[service_index].properties[property_index].set){
        set_string = json_object_get_string(val);
        set_string_len = json_object_get_string_len(val);
        ret = service_table[service_index].properties[property_index].set(&service_table[service_index].properties[property_index], 
                                                                          service_table[service_index].properties[property_index].arg,
                                                                          (void*)set_string, set_string_len);
        if (0 == ret){  // set ok, update property value
          memset((char*)(service_table[service_index].properties[property_index].value), '\0', service_table[service_index].properties[property_index].maxStringLen);
          strncpy((char*)(service_table[service_index].properties[property_index].value), set_string, set_string_len);
          *(service_table[service_index].properties[property_index].value_len) = set_string_len;
          json_object_object_add(out_write_obj, key, json_object_new_string(set_string));
          err = kNoErr;
        }
        else{  // return write err status
          json_object_object_add(out_err_prop_obj, key, json_object_new_int(MICO_PROP_CODE_WRITE_FAILED));
          err = kWriteErr;
        }
      }
      else{ // no set func err
        json_object_object_add(out_err_prop_obj, key, json_object_new_int(MICO_PROP_CODE_NO_SET_FUNC));
        err = kWriteErr;
      }
      break;
    }
    case MICO_PROP_TYPE_BOOL:{
      //properties_log("prop got: %s, iid=%d, value=%d", 
      //               service_table[service_index].properties[property_index].type, iid, 
      //               *((bool*)service_table[service_index].properties[property_index].value));
      // property set(hardware operation)
      if(NULL != service_table[service_index].properties[property_index].set){
        boolean_value = json_object_get_boolean(val);
        ret = service_table[service_index].properties[property_index].set(&service_table[service_index].properties[property_index], 
                                                                          service_table[service_index].properties[property_index].arg,
                                                                          (void*)&boolean_value, sizeof(bool));
        if (0 == ret){  // set ok, update property value
          *((bool*)service_table[service_index].properties[property_index].value) = boolean_value;
          json_object_object_add(out_write_obj, key, json_object_new_boolean(boolean_value));
          err = kNoErr;
        }
        else{  // return write err status
          json_object_object_add(out_err_prop_obj, key, json_object_new_int(MICO_PROP_CODE_WRITE_FAILED));
          err = kWriteErr;
        }
      }
      else{ // no set func err
        json_object_object_add(out_err_prop_obj, key, json_object_new_int(MICO_PROP_CODE_NO_SET_FUNC));
        err = kWriteErr;
      }
      break;
    }
    default:
      properties_log("ERROR: Unsupported format!");
      json_object_object_add(out_err_prop_obj, key, json_object_new_int(MICO_PROP_CODE_DATA_FORMAT_ERR));
      err = kWriteErr;
      break;
    }
  }
  else{
    properties_log("ERROR: property is read only!");
    json_object_object_add(out_err_prop_obj, key, json_object_new_int(MICO_PROP_CODE_NOT_WRITABLE));
    err = kNotWritableErr;
  }
  
exit:
  if(kNotFoundErr == err){   // property not found
    properties_log("ERROR: property not found!");
    json_object_object_add(out_err_prop_obj, key, json_object_new_int(MICO_PROP_CODE_NOT_FOUND));
  }
  if(kRequestErr == err){   // service can not be set
    properties_log("ERROR: service can not be set!");
    json_object_object_add(out_err_prop_obj, key, json_object_new_int(MICO_PROP_CODE_NOT_SUPPORTED));
  }
  return err;
}
예제 #27
0
int application_start(void)
{
  OSStatus err = kNoErr;
  IPStatusTypedef para;
  struct tm currentTime;
  mico_rtc_time_t time;
 
  /*Read current configurations*/
  context = ( mico_Context_t *)malloc(sizeof(mico_Context_t) );
  require_action( context, exit, err = kNoMemoryErr );
  memset(context, 0x0, sizeof(mico_Context_t));
  mico_rtos_init_mutex(&context->flashContentInRam_mutex);
  mico_rtos_init_semaphore(&context->micoStatus.sys_state_change_sem, 1); 

  MICOReadConfiguration( context );

  err = MICOInitNotificationCenter  ( context );

  err = MICOAddNotification( mico_notify_READ_APP_INFO, (void *)micoNotify_ReadAppInfoHandler );
  require_noerr( err, exit );  

  err = MICOAddNotification( mico_notify_WIFI_CONNECT_FAILED, (void *)micoNotify_ConnectFailedHandler );
  require_noerr( err, exit ); 

  err = MICOAddNotification( mico_notify_WIFI_Fatal_ERROR, (void *)micoNotify_WlanFatalErrHandler );
  require_noerr( err, exit ); 

  err = MICOAddNotification( mico_notify_Stack_Overflow_ERROR, (void *)micoNotify_StackOverflowErrHandler );
  require_noerr( err, exit ); 

  /*wlan driver and tcpip init*/
  MicoInit();
  MicoSysLed(true);

  /* Enter test mode, call a build-in test function amd output on STDIO */
  if(MicoShouldEnterMFGMode()==true)
    mico_mfg_test();

  /*Read current time from RTC.*/
  MicoRtcGetTime(&time);
  currentTime.tm_sec = time.sec;
  currentTime.tm_min = time.min;
  currentTime.tm_hour = time.hr;
  currentTime.tm_mday = time.date;
  currentTime.tm_wday = time.weekday;
  currentTime.tm_mon = time.month - 1;
  currentTime.tm_year = time.year + 100;
  mico_log("Current Time: %s",asctime(&currentTime));

  micoWlanGetIPStatus(&para, Station);
  formatMACAddr(context->micoStatus.mac, (char *)&para.mac);
  
  mico_log_trace(); 
  mico_log("%s mxchipWNet library version: %s", APP_INFO, MicoGetVer());

  /*Start system monotor thread*/
  err = MICOStartSystemMonitor(context);
  require_noerr_action( err, exit, mico_log("ERROR: Unable to start the system monitor.") );

  err = MICORegisterSystemMonitor(&mico_monitor, APPLICATION_WATCHDOG_TIMEOUT_SECONDS*1000);
  require_noerr( err, exit );
  mico_init_timer(&_watchdog_reload_timer,APPLICATION_WATCHDOG_TIMEOUT_SECONDS*1000 - 100, _watchdog_reload_timer_handler, NULL);
  mico_start_timer(&_watchdog_reload_timer);
  
  if(context->flashContentInRam.micoSystemConfig.configured != allConfigured){
    mico_log("Empty configuration. Starting configuration mode...");

#if defined (CONFIG_MODE_EASYLINK) || defined (CONFIG_MODE_EASYLINK_WITH_SOFTAP) || defined (CONFIG_MODE_EASYLINK_PLUS)
  err = startEasyLink( context );
  require_noerr( err, exit );
#endif

#if defined (CONFIG_MODE_WPS) || defined (CONFIG_MODE_WPS_WITH_SOFTAP)
  err = startWPS( context );
  require_noerr( err, exit );
#endif

#ifdef CONFIG_MODE_WAC
  WACPlatformParameters_t* WAC_Params = NULL;
  WAC_Params = calloc(1, sizeof(WACPlatformParameters_t));
  require(WAC_Params, exit);

  str2hex((unsigned char *)para.mac, WAC_Params->macAddress, 6);
  WAC_Params->isUnconfigured          = 1;
  WAC_Params->supportsAirPlay         = 0;
  WAC_Params->supportsAirPrint        = 0;
  WAC_Params->supports2_4GHzWiFi      = 1;
  WAC_Params->supports5GHzWiFi        = 0;
  WAC_Params->supportsWakeOnWireless  = 0;

  WAC_Params->firmwareRevision =  FIRMWARE_REVISION;
  WAC_Params->hardwareRevision =  HARDWARE_REVISION;
  WAC_Params->serialNumber =      SERIAL_NUMBER;
  WAC_Params->name =              context->flashContentInRam.micoSystemConfig.name;
  WAC_Params->model =             MODEL;
  WAC_Params->manufacturer =      MANUFACTURER;

  WAC_Params->numEAProtocols =    1;
  WAC_Params->eaBundleSeedID =    BUNDLE_SEED_ID;
  WAC_Params->eaProtocols =       (char **)eaProtocols;;

  err = startMFiWAC( context, WAC_Params, 1200);
  free(WAC_Params);
  require_noerr( err, exit );
#endif
  }
  else{
    mico_log("Available configuration. Starting Wi-Fi connection...");
    
    /* Regisist notifications */
    err = MICOAddNotification( mico_notify_WIFI_STATUS_CHANGED, (void *)micoNotify_WifiStatusHandler );
    require_noerr( err, exit ); 
    
    err = MICOAddNotification( mico_notify_WiFI_PARA_CHANGED, (void *)micoNotify_WiFIParaChangedHandler );
    require_noerr( err, exit ); 

    err = MICOAddNotification( mico_notify_DHCP_COMPLETED, (void *)micoNotify_DHCPCompleteHandler );
    require_noerr( err, exit );  
   
    if(context->flashContentInRam.micoSystemConfig.rfPowerSaveEnable == true){
      micoWlanEnablePowerSave();
    }

    if(context->flashContentInRam.micoSystemConfig.mcuPowerSaveEnable == true){
      MicoMcuPowerSaveConfig(true);
    }

    /*Local configuration server*/
    if(context->flashContentInRam.micoSystemConfig.configServerEnable == true){
      err =  MICOStartConfigServer(context);
      require_noerr_action( err, exit, mico_log("ERROR: Unable to start the local server thread.") );
    }

    err =  MICOStartNTPClient(context);
    require_noerr_action( err, exit, mico_log("ERROR: Unable to start the NTP client thread.") );

    /*Start mico application*/
    err = MICOStartApplication( context );
    require_noerr( err, exit );

    _ConnectToAP( context );
  }

  int free_memory;
  free_memory = MicoGetMemoryInfo()->free_memory;
  REFERENCE_DEBUG_ONLY_VARIABLE(free_memory);
  mico_log("Free memory %d bytes", free_memory) ; 
  
  /*System status changed*/
  while(mico_rtos_get_semaphore(&context->micoStatus.sys_state_change_sem, MICO_WAIT_FOREVER)==kNoErr){
    switch(context->micoStatus.sys_state){
      case eState_Normal:
        break;
      case eState_Software_Reset:
        sendNotifySYSWillPowerOff();
        mico_thread_msleep(500);
        MicoSystemReboot();
        break;
      case eState_Wlan_Powerdown:
        sendNotifySYSWillPowerOff();
        mico_thread_msleep(500);
        micoWlanPowerOff();
        break;
      case eState_Standby:
        mico_log("Enter standby mode");
        sendNotifySYSWillPowerOff();
        mico_thread_msleep(200);
        micoWlanPowerOff();
        MicoSystemStandBy(MICO_WAIT_FOREVER);
        break;
      default:
        break;
    }
  }
    
  require_noerr_action( err, exit, mico_log("Closing main thread with err num: %d.", err) );

exit:
  mico_rtos_delete_thread(NULL);
  return kNoErr;
}
예제 #28
0
json_object* ConfigCreateReportJsonMessage( mico_Context_t * const inContext )
{
  OSStatus err = kNoErr;
  config_delegate_log_trace();
  char name[50], *tempString;
  OTA_Versions_t versions;
  char rfVersion[50];
  char *rfVer = NULL, *rfVerTemp = NULL;
  json_object *sectors, *sector, *subMenuSectors, *subMenuSector, *mainObject = NULL;

  MicoGetRfVer( rfVersion, 50 );
  rfVer = strstr(rfVersion, "version ");
  if(rfVer) rfVer = rfVer + strlen("version ");
  rfVerTemp = rfVer;

  for(rfVerTemp = rfVer; *rfVerTemp != ' '; rfVerTemp++);
  *rfVerTemp = 0x0;
  
  config_delegate_log("RF version=%s", rfVersion);

  if(inContext->flashContentInRam.micoSystemConfig.configured == wLanUnConfigured){
    /*You can upload a specific menu*/
  }

  mico_rtos_lock_mutex(&inContext->flashContentInRam_mutex);
  snprintf(name, 50, "%s(%c%c%c%c%c%c)",MODEL, 
                                        inContext->micoStatus.mac[9],  inContext->micoStatus.mac[10], 
                                        inContext->micoStatus.mac[12], inContext->micoStatus.mac[13],
                                        inContext->micoStatus.mac[15], inContext->micoStatus.mac[16]);

  versions.fwVersion = FIRMWARE_REVISION;
  versions.hdVersion = HARDWARE_REVISION;
  versions.protocol =  PROTOCOL;
  versions.rfVersion = NULL;

  sectors = json_object_new_array();
  require( sectors, exit );

  err = MICOAddTopMenu(&mainObject, name, sectors, versions);
  require_noerr(err, exit);

  /*Sector 1*/
  sector = json_object_new_array();
  require( sector, exit );
  err = MICOAddSector(sectors, "MICO SYSTEM",    sector);
  require_noerr(err, exit);

    /*name cell*/
    err = MICOAddStringCellToSector(sector, "Device Name",    inContext->flashContentInRam.micoSystemConfig.name,               "RW", NULL);
    require_noerr(err, exit);

    //Bonjour switcher cell
    err = MICOAddSwitchCellToSector(sector, "Bonjour",        inContext->flashContentInRam.micoSystemConfig.bonjourEnable,      "RW");
    require_noerr(err, exit);

    //RF power save switcher cell
    err = MICOAddSwitchCellToSector(sector, "RF power save",  inContext->flashContentInRam.micoSystemConfig.rfPowerSaveEnable,  "RW");
    require_noerr(err, exit);

    //MCU power save switcher cell
    err = MICOAddSwitchCellToSector(sector, "MCU power save", inContext->flashContentInRam.micoSystemConfig.mcuPowerSaveEnable, "RW");
    require_noerr(err, exit);

    /*sub menu*/
    subMenuSectors = json_object_new_array();
    require( subMenuSectors, exit );
    err = MICOAddMenuCellToSector(sector, "Detail", subMenuSectors);
    require_noerr(err, exit);
      
      subMenuSector = json_object_new_array();
      require( subMenuSector, exit );
      err = MICOAddSector(subMenuSectors,  "",    subMenuSector);
      require_noerr(err, exit);

        err = MICOAddStringCellToSector(subMenuSector, "Firmware Rev.",  FIRMWARE_REVISION, "RO", NULL);
        require_noerr(err, exit);
        err = MICOAddStringCellToSector(subMenuSector, "Hardware Rev.",  HARDWARE_REVISION, "RO", NULL);
        require_noerr(err, exit);
        err = MICOAddStringCellToSector(subMenuSector, "MICO OS Rev.",   MicoGetVer(),      "RO", NULL);
        require_noerr(err, exit);
        err = MICOAddStringCellToSector(subMenuSector, "RF Driver Rev.", rfVer,             "RO", NULL);
        require_noerr(err, exit);
        err = MICOAddStringCellToSector(subMenuSector, "Model",          MODEL,             "RO", NULL);
        require_noerr(err, exit);
        err = MICOAddStringCellToSector(subMenuSector, "Manufacturer",   MANUFACTURER,      "RO", NULL);
        require_noerr(err, exit);
        err = MICOAddStringCellToSector(subMenuSector, "Protocol",       PROTOCOL,          "RO", NULL);
        require_noerr(err, exit);

      subMenuSector = json_object_new_array();
      err = MICOAddSector(subMenuSectors,  "WLAN",    subMenuSector);
      require_noerr(err, exit);
      
        tempString = DataToHexStringWithColons( (uint8_t *)inContext->flashContentInRam.micoSystemConfig.bssid, 6 );
        err = MICOAddStringCellToSector(subMenuSector, "BSSID",        tempString, "RO", NULL);
        require_noerr(err, exit);
        free(tempString);

        err = MICOAddNumberCellToSector(subMenuSector, "Channel",      inContext->flashContentInRam.micoSystemConfig.channel, "RO", NULL);
        require_noerr(err, exit);

        switch(inContext->flashContentInRam.micoSystemConfig.security){
          case SECURITY_TYPE_NONE:
            err = MICOAddStringCellToSector(subMenuSector, "Security",   "Open system", "RO", NULL); 
            break;
          case SECURITY_TYPE_WEP:
            err = MICOAddStringCellToSector(subMenuSector, "Security",   "WEP",         "RO", NULL); 
            break;
          case SECURITY_TYPE_WPA_TKIP:
            err = MICOAddStringCellToSector(subMenuSector, "Security",   "WPA TKIP",    "RO", NULL); 
            break;
          case SECURITY_TYPE_WPA_AES:
            err = MICOAddStringCellToSector(subMenuSector, "Security",   "WPA AES",     "RO", NULL); 
            break;
          case SECURITY_TYPE_WPA2_TKIP:
            err = MICOAddStringCellToSector(subMenuSector, "Security",   "WPA2 TKIP",   "RO", NULL); 
            break;
          case SECURITY_TYPE_WPA2_AES:
            err = MICOAddStringCellToSector(subMenuSector, "Security",   "WPA2 AES",    "RO", NULL); 
            break;
          case SECURITY_TYPE_WPA2_MIXED:
            err = MICOAddStringCellToSector(subMenuSector, "Security",   "WPA2 MIXED",  "RO", NULL); 
            break;
          default:
            err = MICOAddStringCellToSector(subMenuSector, "Security",   "Auto",      "RO", NULL); 
            break;
        }
        require_noerr(err, exit); 

        if(inContext->flashContentInRam.micoSystemConfig.keyLength == maxKeyLen){ /*This is a PMK key, generated by user key in WPA security type*/
          tempString = calloc(maxKeyLen+1, 1);
          require_action(tempString, exit, err=kNoMemoryErr);
          memcpy(tempString, inContext->flashContentInRam.micoSystemConfig.key, maxKeyLen);
          err = MICOAddStringCellToSector(subMenuSector, "PMK",          tempString, "RO", NULL);
          require_noerr(err, exit);
          free(tempString);
        }
        else{
          err = MICOAddStringCellToSector(subMenuSector, "KEY",          inContext->flashContentInRam.micoSystemConfig.user_key,  "RO", NULL);
          require_noerr(err, exit);
        }

  /*Sector 3*/
  sector = json_object_new_array();
  require( sector, exit );
  err = MICOAddSector(sectors, "WLAN",           sector);
  require_noerr(err, exit);
    /*SSID cell*/
    err = MICOAddStringCellToSector(sector, "Wi-Fi",        inContext->flashContentInRam.micoSystemConfig.ssid,     "RW", NULL);
    require_noerr(err, exit);
    /*PASSWORD cell*/
    err = MICOAddStringCellToSector(sector, "Password",     inContext->flashContentInRam.micoSystemConfig.user_key, "RW", NULL);
    require_noerr(err, exit);
    /*DHCP cell*/
    err = MICOAddSwitchCellToSector(sector, "DHCP",        inContext->flashContentInRam.micoSystemConfig.dhcpEnable,   "RW");
    require_noerr(err, exit);
    /*Local cell*/
    err = MICOAddStringCellToSector(sector, "IP address",  inContext->micoStatus.localIp,   "RW", NULL);
    require_noerr(err, exit);
    /*Netmask cell*/
    err = MICOAddStringCellToSector(sector, "Net Mask",    inContext->micoStatus.netMask,   "RW", NULL);
    require_noerr(err, exit);
    /*Gateway cell*/
    err = MICOAddStringCellToSector(sector, "Gateway",     inContext->micoStatus.gateWay,   "RW", NULL);
    require_noerr(err, exit);
    /*DNS server cell*/
    err = MICOAddStringCellToSector(sector, "DNS Server",  inContext->micoStatus.dnsServer, "RW", NULL);
    require_noerr(err, exit);

  /*Sector 4*/

  /*Sector 5*/
  sector = json_object_new_array();
  require( sector, exit );
  err = MICOAddSector(sectors, "MCU IOs",            sector);
  require_noerr(err, exit);

    /*UART Baurdrate cell*/
    json_object *selectArray;
    selectArray = json_object_new_array();
    require( selectArray, exit );
    json_object_array_add(selectArray, json_object_new_int(9600));
    json_object_array_add(selectArray, json_object_new_int(19200));
    json_object_array_add(selectArray, json_object_new_int(38400));
    json_object_array_add(selectArray, json_object_new_int(57600));
    json_object_array_add(selectArray, json_object_new_int(115200));
    //err = MICOAddNumberCellToSector(sector, "Baurdrate", 115200, "RW", selectArray);
    err = MICOAddNumberCellToSector(sector, "Baurdrate", 
              inContext->flashContentInRam.appConfig.virtualDevConfig.USART_BaudRate, 
              "RW", selectArray);
    require_noerr(err, exit);
    
  /*Sector 6: cloud settings*/
  sector = json_object_new_array();
  require( sector, exit );
  err = MICOAddSector(sectors, "Cloud info", sector);
  require_noerr(err, exit);
  
  // device activate status
  err = MICOAddSwitchCellToSector(sector, "activated", 
                                  inContext->flashContentInRam.appConfig.virtualDevConfig.isActivated, 
                                  "RO");
  require_noerr(err, exit);
  // cloud connect status
  err = MICOAddSwitchCellToSector(sector, "connected", 
                                  inContext->appStatus.virtualDevStatus.isCloudConnected, 
                                  "RO");
  require_noerr(err, exit);
  // rom version cell
  err = MICOAddStringCellToSector(sector, "rom version", 
                                  inContext->flashContentInRam.appConfig.virtualDevConfig.romVersion,
                                  "RO", NULL);
  require_noerr(err, exit);
  // device_id cell, is RO in fact, we set RW is convenient for read full string.
  err = MICOAddStringCellToSector(sector, "device_id", 
                                  inContext->flashContentInRam.appConfig.virtualDevConfig.deviceId,
                                  "RW", NULL);
  /*sub menu - cloud setting */
/*  subMenuSectors = json_object_new_array();
  require( subMenuSectors, exit );
  err = MICOAddMenuCellToSector(sector, "Cloud settings", subMenuSectors);
  require_noerr(err, exit);
  
  subMenuSector = json_object_new_array();
  require( subMenuSector, exit );
  err = MICOAddSector(subMenuSectors, "Authentication", subMenuSector);
  require_noerr(err, exit);
  
  err = MICOAddStringCellToSector(subMenuSector, "login_id",  
                                  inContext->flashContentInRam.appConfig.virtualDevConfig.loginId,
                                  "RW", NULL);
  err = MICOAddStringCellToSector(subMenuSector, "devPasswd",  
                                  inContext->flashContentInRam.appConfig.virtualDevConfig.devPasswd,
                                  "RW", NULL);
*/
  mico_rtos_unlock_mutex(&inContext->flashContentInRam_mutex);
  
exit:
  if(err != kNoErr && mainObject){
    json_object_put(mainObject);
    mainObject = NULL;
  }
  return mainObject;
}
예제 #29
0
/*
 * SecCmsSignedDataEncodeAfterData - do all the necessary things to a SignedData
 *     after all the encapsulated data was passed through the encoder.
 *
 * In detail:
 *  - create the signatures in all the SignerInfos
 *
 * Please note that nothing is done to the Certificates and CRLs in the message - this
 * is entirely the responsibility of our callers.
 */
OSStatus
SecCmsSignedDataEncodeAfterData(SecCmsSignedDataRef sigd)
{
    SecCmsSignerInfoRef *signerinfos, signerinfo;
    SecCmsContentInfoRef cinfo;
    SECOidTag digestalgtag;
    OSStatus ret = SECFailure;
    OSStatus rv;
    CSSM_DATA_PTR contentType;
    int certcount;
    int i, ci, n, rci, si;
    PLArenaPool *poolp;
    CFArrayRef certlist;
    extern const SecAsn1Template SecCmsSignerInfoTemplate[];

    poolp = sigd->cmsg->poolp;
    cinfo = &(sigd->contentInfo);

    /* did we have digest calculation going on? */
    if (cinfo->digcx) {
	rv = SecCmsDigestContextFinishMultiple(cinfo->digcx, (SecArenaPoolRef)poolp, &(sigd->digests));
	if (rv != SECSuccess)
	    goto loser;		/* error has been set by SecCmsDigestContextFinishMultiple */
	cinfo->digcx = NULL;
    }

    signerinfos = sigd->signerInfos;
    certcount = 0;

    /* prepare all the SignerInfos (there may be none) */
    for (i=0; i < SecCmsSignedDataSignerInfoCount(sigd); i++) {
	signerinfo = SecCmsSignedDataGetSignerInfo(sigd, i);
	
	/* find correct digest for this signerinfo */
	digestalgtag = SecCmsSignerInfoGetDigestAlgTag(signerinfo);
	n = SecCmsAlgArrayGetIndexByAlgTag(sigd->digestAlgorithms, digestalgtag);
	if (n < 0 || sigd->digests == NULL || sigd->digests[n] == NULL) {
	    /* oops - digest not found */
	    PORT_SetError(SEC_ERROR_DIGEST_NOT_FOUND);
	    goto loser;
	}

	/* XXX if our content is anything else but data, we need to force the
	 * presence of signed attributes (RFC2630 5.3 "signedAttributes is a
	 * collection...") */

	/* pass contentType here as we want a contentType attribute */
	if ((contentType = SecCmsContentInfoGetContentTypeOID(cinfo)) == NULL)
	    goto loser;

	/* sign the thing */
	rv = SecCmsSignerInfoSign(signerinfo, sigd->digests[n], contentType);
	if (rv != SECSuccess)
	    goto loser;

	/* while we're at it, count number of certs in certLists */
	certlist = SecCmsSignerInfoGetCertList(signerinfo);
	if (certlist)
	    certcount += CFArrayGetCount(certlist);
    }

    /* Now we can get a timestamp, since we have all the digests */

    // We force the setting of a callback, since this is the most usual case
    if (!sigd->cmsg->tsaCallback)
        SecCmsMessageSetTSACallback(sigd->cmsg, (SecCmsTSACallback)SecCmsTSADefaultCallback);
        
    if (sigd->cmsg->tsaCallback && sigd->cmsg->tsaContext)
    {
        CSSM_DATA tsaResponse = {0,};
        SecAsn1TSAMessageImprint messageImprint = {{{0},},{0,}};
        // <rdar://problem/11073466> Add nonce support for timestamping client

        uint64_t nonce = 0;

        require_noerr(getRandomNonce(&nonce), tsxit);
        dprintf("SecCmsSignedDataSignerInfoCount: %d\n", SecCmsSignedDataSignerInfoCount(sigd));

        // Calculate hash of encDigest and put in messageImprint.hashedMessage
        SecCmsSignerInfoRef signerinfo = SecCmsSignedDataGetSignerInfo(sigd, 0);    // NB - assume 1 signer only!
        CSSM_DATA *encDigest = SecCmsSignerInfoGetEncDigest(signerinfo);
        require_noerr(createTSAMessageImprint(sigd, encDigest, &messageImprint), tsxit);
        
        // Callback to fire up XPC service to talk to TimeStamping server, etc.
        require_noerr(rv =(*sigd->cmsg->tsaCallback)(sigd->cmsg->tsaContext, &messageImprint,
                                                     nonce, &tsaResponse), tsxit);
        
        require_noerr(rv = validateTSAResponseAndAddTimeStamp(signerinfo, &tsaResponse, nonce), tsxit);

        /*
            It is likely that every occurrence of "goto loser" in this file should
            also do a PORT_SetError. Since it is not clear what might depend on this
            behavior, we just do this in the timestamping case.
        */
tsxit:
        if (rv)
        {
            dprintf("Original timestamp error: %d\n", (int)rv);
            rv = remapTimestampError(rv);
            PORT_SetError(rv);
            goto loser;
        }
    }
        
    /* this is a SET OF, so we need to sort them guys */
    rv = SecCmsArraySortByDER((void **)signerinfos, SecCmsSignerInfoTemplate, NULL);
    if (rv != SECSuccess)
	goto loser;

    /*
     * now prepare certs & crls
     */

    /* count the rest of the certs */
    if (sigd->certs != NULL)
	certcount += CFArrayGetCount(sigd->certs);

    if (certcount == 0) {
	sigd->rawCerts = NULL;
    } else {
	/*
	 * Combine all of the certs and cert chains into rawcerts.
	 * Note: certcount is an upper bound; we may not need that many slots
	 * but we will allocate anyway to avoid having to do another pass.
	 * (The temporary space saving is not worth it.)
	 *
	 * XXX ARGH - this NEEDS to be fixed. need to come up with a decent
	 *  SetOfDERcertficates implementation
	 */
	sigd->rawCerts = (CSSM_DATA_PTR *)PORT_ArenaAlloc(poolp, (certcount + 1) * sizeof(CSSM_DATA_PTR));
	if (sigd->rawCerts == NULL)
	    return SECFailure;

	/*
	 * XXX Want to check for duplicates and not add *any* cert that is
	 * already in the set.  This will be more important when we start
	 * dealing with larger sets of certs, dual-key certs (signing and
	 * encryption), etc.  For the time being we can slide by...
	 *
	 * XXX ARGH - this NEEDS to be fixed. need to come up with a decent
	 *  SetOfDERcertficates implementation
	 */
	rci = 0;
	if (signerinfos != NULL) {
	    for (si = 0; signerinfos[si] != NULL; si++) {
		signerinfo = signerinfos[si];
		for (ci = 0; ci < CFArrayGetCount(signerinfo->certList); ci++) {
		    sigd->rawCerts[rci] = PORT_ArenaZAlloc(poolp, sizeof(CSSM_DATA));
		    SecCertificateRef cert = (SecCertificateRef)CFArrayGetValueAtIndex(signerinfo->certList, ci);
		    SecCertificateGetData(cert, sigd->rawCerts[rci++]);
		}
	    }
	}

	if (sigd->certs != NULL) {
	    for (ci = 0; ci < CFArrayGetCount(sigd->certs); ci++) {
		sigd->rawCerts[rci] = PORT_ArenaZAlloc(poolp, sizeof(CSSM_DATA));
		SecCertificateRef cert = (SecCertificateRef)CFArrayGetValueAtIndex(sigd->certs, ci);
		SecCertificateGetData(cert, sigd->rawCerts[rci++]);
	    }
	}

	sigd->rawCerts[rci] = NULL;

	/* this is a SET OF, so we need to sort them guys - we have the DER already, though */
	SecCmsArraySort((void **)sigd->rawCerts, SecCmsUtilDERCompare, NULL, NULL);
    }

    ret = SECSuccess;

loser:

    dprintf("SecCmsSignedDataEncodeAfterData: ret: %ld, rv: %ld\n", (long)ret, (long)rv);
    return ret;
}
예제 #30
0
smcp_status_t
smcp_variable_node_request_handler(
	smcp_variable_node_t		node
) {
	// TODO: Make this function use less stack space!

	smcp_method_t method = smcp_inbound_get_code();
	smcp_status_t ret = SMCP_STATUS_NOT_FOUND;
	coap_content_type_t content_type = smcp_inbound_get_content_type();
	char* content_ptr = (char*)smcp_inbound_get_content_ptr();
	size_t content_len = smcp_inbound_get_content_len();
	SMCP_NON_RECURSIVE char buffer[SMCP_VARIABLE_MAX_VALUE_LENGTH+1];
	SMCP_NON_RECURSIVE coap_content_type_t reply_content_type;
	uint8_t key_index = BAD_KEY_INDEX;
	size_t value_len;
	bool needs_prefix = true;
	char* prefix_name = "";

	reply_content_type = SMCP_CONTENT_TYPE_APPLICATION_FORM_URLENCODED;

	require(node, bail);

	// Look up the key index.
	if(smcp_inbound_peek_option(NULL,&value_len)==COAP_OPTION_URI_PATH) {
		if(!value_len) {
			needs_prefix = false;
			smcp_inbound_next_option(NULL,NULL);
		} else for(key_index=0;key_index<BAD_KEY_INDEX;key_index++) {
			ret = node->func(node,SMCP_VAR_GET_KEY,key_index,buffer);
			require_action(ret==0,bail,ret=SMCP_STATUS_NOT_FOUND);
			if(smcp_inbound_option_strequal(COAP_OPTION_URI_PATH, buffer)) {
				smcp_inbound_next_option(NULL,NULL);
				break;
			}
		}
	}

	{
		coap_option_key_t key;
		const uint8_t* value;
		while((key=smcp_inbound_next_option(&value, &value_len))!=COAP_OPTION_INVALID) {
			require_action(key!=COAP_OPTION_URI_PATH,bail,ret=SMCP_STATUS_NOT_FOUND);
			if(key==COAP_OPTION_URI_QUERY) {
				if(	method == COAP_METHOD_POST
					&& value_len>=2
					&& strhasprefix_const((const char*)value,"v=")
				) {
					DEBUG_PRINTF("variable-node: value is in the query.");
					content_type = COAP_CONTENT_TYPE_TEXT_PLAIN;
					content_ptr = (char*)value+2;
					content_len = value_len-2;
				}
//			} else if(key==COAP_OPTION_ETAG) {
//			} else if(key==COAP_OPTION_IF_MATCH) {
//			} else if(key==COAP_OPTION_IF_NONE_MATCH) {
			} else if(key==COAP_OPTION_ACCEPT) {
				reply_content_type = 0;
				if(value_len==1)
					reply_content_type = value[0];
				else {
					// Unsupported type.
				}
			} else if(COAP_OPTION_IS_CRITICAL(key)) {
				ret=SMCP_STATUS_BAD_OPTION;
				assert_printf("Unrecognized option %d, \"%s\"",
					key,
					coap_option_key_to_cstr(key, false)
				);
				goto bail;
			}
		}
	}

	// TODO: Implement me!
	if(method == COAP_METHOD_PUT)
		method = COAP_METHOD_POST;

	if(method == COAP_METHOD_POST) {
		require_action(!smcp_inbound_is_dupe(),bail,ret=0);

		require_action(
			key_index!=BAD_KEY_INDEX,
			bail,
			ret=SMCP_STATUS_NOT_ALLOWED
		);
		if(content_type==SMCP_CONTENT_TYPE_APPLICATION_FORM_URLENCODED) {
			char* key = NULL;
			char* value = NULL;
			content_len = 0;
			while(
				url_form_next_value(
					(char**)&content_ptr,
					&key,
					&value
				)
				&& key
				&& value
			) {
				if(strequal_const(key, "v")) {
					content_ptr = value;
					content_len = strlen(value);
					break;
				}
			}
		}

		// Make sure our content is zero terminated.
		((char*)content_ptr)[content_len] = 0;

		ret = node->func(node,SMCP_VAR_SET_VALUE,key_index,(char*)content_ptr);
		require_noerr(ret,bail);

		ret = smcp_outbound_begin_response(COAP_RESULT_204_CHANGED);
		require_noerr(ret,bail);

		ret = smcp_outbound_send();
		require_noerr(ret,bail);
	} else if(method == COAP_METHOD_GET) {

		if(key_index==BAD_KEY_INDEX) {
			char* content_end_ptr;

			ret = smcp_outbound_begin_response(COAP_RESULT_205_CONTENT);
			require_noerr(ret,bail);

			smcp_outbound_add_option_uint(COAP_OPTION_CONTENT_TYPE, COAP_CONTENT_TYPE_APPLICATION_LINK_FORMAT);

			ret = smcp_observable_update(&node->observable, SMCP_OBSERVABLE_BROADCAST_KEY);
			check_string(ret==0,smcp_status_to_cstr(ret));

			content_ptr = smcp_outbound_get_content_ptr(&content_len);
			content_end_ptr = content_ptr+content_len;

			for(key_index=0;key_index<BAD_KEY_INDEX;key_index++) {
				ret = node->func(node,SMCP_VAR_GET_KEY,key_index,buffer);
				if(ret) break;

				if(content_ptr+2>=content_end_ptr) {
					// No more room for content.
					break;
				}

				*content_ptr++ = '<';
				if(needs_prefix) {
					content_ptr += url_encode_cstr(content_ptr, prefix_name, (content_end_ptr-content_ptr)-1);
					content_ptr = stpncpy(content_ptr,"/",(content_end_ptr-content_ptr)-1);
				}
				content_ptr += url_encode_cstr(content_ptr, buffer, (content_end_ptr-content_ptr)-1);
				*content_ptr++ = '>';

				ret = node->func(node,SMCP_VAR_GET_VALUE,key_index,buffer);

				if(content_ptr+4>=content_end_ptr) {
					// No more room for content.
					break;
				}

				if(!ret) {
					strcpy(content_ptr,";v=");
					content_ptr += 3;
					content_ptr += quoted_cstr(content_ptr, buffer, (content_end_ptr-content_ptr)-1);
				}

				ret = node->func(node,SMCP_VAR_GET_LF_TITLE,key_index,buffer);

				if(content_ptr+8>=content_end_ptr) {
					// No more room for content.
					break;
				}

				if(!ret) {
					strcpy(content_ptr,";title=");
					content_ptr += 7;
					content_ptr += quoted_cstr(content_ptr, buffer, (content_end_ptr-content_ptr)-1);
				}

				// Observation flag
				if(0==node->func(node,SMCP_VAR_GET_OBSERVABLE,key_index,NULL))
					content_ptr = stpncpy(content_ptr,";obs",(content_end_ptr-content_ptr)-1);

				*content_ptr++ = ',';
			}
			ret = smcp_outbound_set_content_len(content_len-(content_end_ptr-content_ptr));
			require_noerr(ret,bail);

			ret = smcp_outbound_send();
		} else {
			size_t replyContentLength = 0;
			char *replyContent;

			ret = smcp_outbound_begin_response(COAP_RESULT_205_CONTENT);
			require_noerr(ret,bail);

			if(0==node->func(node,SMCP_VAR_GET_OBSERVABLE,key_index,buffer)) {
				ret = smcp_observable_update(&node->observable, key_index);
				check_string(ret==0,smcp_status_to_cstr(ret));
			}

			if(reply_content_type == SMCP_CONTENT_TYPE_APPLICATION_FORM_URLENCODED) {
				uint32_t etag;

				if(0==node->func(node,SMCP_VAR_GET_MAX_AGE,key_index,buffer)) {
#if HAVE_STRTOL
					uint32_t max_age = strtol(buffer,NULL,0)&0xFFFFFF;
#else
					uint32_t max_age = atoi(buffer)&0xFFFFFF;
#endif
					smcp_outbound_add_option_uint(COAP_OPTION_MAX_AGE, max_age);
				}

				ret = node->func(node,SMCP_VAR_GET_VALUE,key_index,buffer);
				require_noerr(ret,bail);

				fasthash_start(0);
				fasthash_feed((const uint8_t*)buffer,strlen(buffer));
				etag = fasthash_finish_uint32();

				smcp_outbound_add_option_uint(COAP_OPTION_CONTENT_TYPE, SMCP_CONTENT_TYPE_APPLICATION_FORM_URLENCODED);

				smcp_outbound_add_option_uint(COAP_OPTION_ETAG, etag);

				replyContent = smcp_outbound_get_content_ptr(&replyContentLength);

				*replyContent++ = 'v';
				*replyContent++ = '=';
				replyContentLength -= 2;
				replyContentLength = url_encode_cstr(
					replyContent,
					buffer,
					replyContentLength
				);
				ret = smcp_outbound_set_content_len(replyContentLength+2);
			} else {
				ret = node->func(node,SMCP_VAR_GET_VALUE,key_index,buffer);
				require_noerr(ret,bail);

				ret = smcp_outbound_append_content(buffer, SMCP_CSTR_LEN);
			}

			require_noerr(ret,bail);

			ret = smcp_outbound_send();
		}
	} else {
		ret = smcp_default_request_handler(
			(void*)node
		);
		check_string(ret == SMCP_STATUS_OK, smcp_status_to_cstr(ret));
	}

bail:
	check_string(ret == SMCP_STATUS_OK, smcp_status_to_cstr(ret));
	return ret;
}